@seed-ship/mcp-ui-solid 6.19.1 → 6.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +663 -0
- package/README.md +911 -4
- package/dist/adapters/connector.cjs +15 -4
- package/dist/adapters/connector.cjs.map +1 -1
- package/dist/adapters/connector.d.ts +38 -0
- package/dist/adapters/connector.d.ts.map +1 -1
- package/dist/adapters/connector.js +15 -4
- package/dist/adapters/connector.js.map +1 -1
- package/dist/adapters/index.d.ts +4 -3
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/macro-run.cjs +25 -13
- package/dist/adapters/macro-run.cjs.map +1 -1
- package/dist/adapters/macro-run.d.ts +37 -2
- package/dist/adapters/macro-run.d.ts.map +1 -1
- package/dist/adapters/macro-run.js +25 -13
- package/dist/adapters/macro-run.js.map +1 -1
- package/dist/adapters.cjs +2 -0
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.js +4 -2
- package/dist/components/ActionGroupRenderer.cjs +3 -1
- package/dist/components/ActionGroupRenderer.cjs.map +1 -1
- package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
- package/dist/components/ActionGroupRenderer.js +3 -1
- package/dist/components/ActionGroupRenderer.js.map +1 -1
- package/dist/components/AgentCard.cjs +11 -8
- package/dist/components/AgentCard.cjs.map +1 -1
- package/dist/components/AgentCard.d.ts.map +1 -1
- package/dist/components/AgentCard.js +11 -8
- package/dist/components/AgentCard.js.map +1 -1
- package/dist/components/AgentHandoff.cjs +6 -1
- package/dist/components/AgentHandoff.cjs.map +1 -1
- package/dist/components/AgentHandoff.d.ts.map +1 -1
- package/dist/components/AgentHandoff.js +6 -1
- package/dist/components/AgentHandoff.js.map +1 -1
- package/dist/components/ArtifactRenderer.cjs +25 -6
- package/dist/components/ArtifactRenderer.cjs.map +1 -1
- package/dist/components/ArtifactRenderer.d.ts.map +1 -1
- package/dist/components/ArtifactRenderer.js +25 -6
- package/dist/components/ArtifactRenderer.js.map +1 -1
- package/dist/components/AutocompleteDropdown.cjs +30 -24
- package/dist/components/AutocompleteDropdown.cjs.map +1 -1
- package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
- package/dist/components/AutocompleteDropdown.js +30 -24
- package/dist/components/AutocompleteDropdown.js.map +1 -1
- package/dist/components/AutocompleteFormField.cjs +3 -1
- package/dist/components/AutocompleteFormField.cjs.map +1 -1
- package/dist/components/AutocompleteFormField.d.ts.map +1 -1
- package/dist/components/AutocompleteFormField.js +4 -2
- package/dist/components/AutocompleteFormField.js.map +1 -1
- package/dist/components/BriefingDiff.cjs +45 -39
- package/dist/components/BriefingDiff.cjs.map +1 -1
- package/dist/components/BriefingDiff.d.ts.map +1 -1
- package/dist/components/BriefingDiff.js +45 -39
- package/dist/components/BriefingDiff.js.map +1 -1
- package/dist/components/CarouselRenderer.cjs +8 -2
- package/dist/components/CarouselRenderer.cjs.map +1 -1
- package/dist/components/CarouselRenderer.d.ts.map +1 -1
- package/dist/components/CarouselRenderer.js +8 -2
- package/dist/components/CarouselRenderer.js.map +1 -1
- package/dist/components/ChartJSRenderer.cjs +60 -36
- package/dist/components/ChartJSRenderer.cjs.map +1 -1
- package/dist/components/ChartJSRenderer.d.ts.map +1 -1
- package/dist/components/ChartJSRenderer.js +61 -37
- package/dist/components/ChartJSRenderer.js.map +1 -1
- package/dist/components/ChatPrompt.cjs +15 -9
- package/dist/components/ChatPrompt.cjs.map +1 -1
- package/dist/components/ChatPrompt.d.ts.map +1 -1
- package/dist/components/ChatPrompt.js +15 -9
- package/dist/components/ChatPrompt.js.map +1 -1
- package/dist/components/CodeBlockRenderer.cjs +34 -16
- package/dist/components/CodeBlockRenderer.cjs.map +1 -1
- package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/components/CodeBlockRenderer.js +34 -16
- package/dist/components/CodeBlockRenderer.js.map +1 -1
- package/dist/components/DataPreviewSection.cjs +91 -44
- package/dist/components/DataPreviewSection.cjs.map +1 -1
- package/dist/components/DataPreviewSection.d.ts.map +1 -1
- package/dist/components/DataPreviewSection.js +92 -45
- package/dist/components/DataPreviewSection.js.map +1 -1
- package/dist/components/DegradedFallback.cjs +20 -16
- package/dist/components/DegradedFallback.cjs.map +1 -1
- package/dist/components/DegradedFallback.d.ts.map +1 -1
- package/dist/components/DegradedFallback.js +20 -16
- package/dist/components/DegradedFallback.js.map +1 -1
- package/dist/components/FooterRenderer.cjs +21 -17
- package/dist/components/FooterRenderer.cjs.map +1 -1
- package/dist/components/FooterRenderer.d.ts.map +1 -1
- package/dist/components/FooterRenderer.js +21 -17
- package/dist/components/FooterRenderer.js.map +1 -1
- package/dist/components/FormFieldRenderer.cjs +116 -93
- package/dist/components/FormFieldRenderer.cjs.map +1 -1
- package/dist/components/FormFieldRenderer.d.ts.map +1 -1
- package/dist/components/FormFieldRenderer.js +116 -93
- package/dist/components/FormFieldRenderer.js.map +1 -1
- package/dist/components/FormRenderer.cjs +55 -31
- package/dist/components/FormRenderer.cjs.map +1 -1
- package/dist/components/FormRenderer.d.ts.map +1 -1
- package/dist/components/FormRenderer.js +55 -31
- package/dist/components/FormRenderer.js.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js +20 -15
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
- package/dist/components/GraphRenderer.cjs +56 -33
- package/dist/components/GraphRenderer.cjs.map +1 -1
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +56 -33
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/IframeFallbackLink.cjs +37 -0
- package/dist/components/IframeFallbackLink.cjs.map +1 -0
- package/dist/components/IframeFallbackLink.d.ts +23 -0
- package/dist/components/IframeFallbackLink.d.ts.map +1 -0
- package/dist/components/IframeFallbackLink.js +37 -0
- package/dist/components/IframeFallbackLink.js.map +1 -0
- package/dist/components/ImageGalleryRenderer.cjs +13 -4
- package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
- package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
- package/dist/components/ImageGalleryRenderer.js +13 -4
- package/dist/components/ImageGalleryRenderer.js.map +1 -1
- package/dist/components/LightboxOverlay.cjs +16 -8
- package/dist/components/LightboxOverlay.cjs.map +1 -1
- package/dist/components/LightboxOverlay.d.ts.map +1 -1
- package/dist/components/LightboxOverlay.js +17 -9
- package/dist/components/LightboxOverlay.js.map +1 -1
- package/dist/components/MapRenderer.cjs +59 -29
- package/dist/components/MapRenderer.cjs.map +1 -1
- package/dist/components/MapRenderer.d.ts +10 -2
- package/dist/components/MapRenderer.d.ts.map +1 -1
- package/dist/components/MapRenderer.js +60 -30
- package/dist/components/MapRenderer.js.map +1 -1
- package/dist/components/ModalRenderer.cjs +4 -1
- package/dist/components/ModalRenderer.cjs.map +1 -1
- package/dist/components/ModalRenderer.d.ts.map +1 -1
- package/dist/components/ModalRenderer.js +5 -2
- package/dist/components/ModalRenderer.js.map +1 -1
- package/dist/components/ScratchpadPanel.cjs +578 -535
- package/dist/components/ScratchpadPanel.cjs.map +1 -1
- package/dist/components/ScratchpadPanel.d.ts.map +1 -1
- package/dist/components/ScratchpadPanel.js +578 -535
- package/dist/components/ScratchpadPanel.js.map +1 -1
- package/dist/components/StreamingUIRenderer.cjs +92 -28
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +92 -28
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +481 -365
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts +21 -0
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +484 -368
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/components/VerifiedText.cjs +39 -20
- package/dist/components/VerifiedText.cjs.map +1 -1
- package/dist/components/VerifiedText.d.ts +2 -1
- package/dist/components/VerifiedText.d.ts.map +1 -1
- package/dist/components/VerifiedText.js +39 -20
- package/dist/components/VerifiedText.js.map +1 -1
- package/dist/components/VideoRenderer.cjs +51 -20
- package/dist/components/VideoRenderer.cjs.map +1 -1
- package/dist/components/VideoRenderer.d.ts.map +1 -1
- package/dist/components/VideoRenderer.js +51 -20
- package/dist/components/VideoRenderer.js.map +1 -1
- package/dist/components/chart-data-table.cjs +38 -17
- package/dist/components/chart-data-table.cjs.map +1 -1
- package/dist/components/chart-data-table.d.ts +30 -1
- package/dist/components/chart-data-table.d.ts.map +1 -1
- package/dist/components/chart-data-table.js +38 -17
- package/dist/components/chart-data-table.js.map +1 -1
- package/dist/context/MCPActionContext.cjs +3 -1
- package/dist/context/MCPActionContext.cjs.map +1 -1
- package/dist/context/MCPActionContext.d.ts.map +1 -1
- package/dist/context/MCPActionContext.js +3 -1
- package/dist/context/MCPActionContext.js.map +1 -1
- package/dist/context/MCPUIConfigContext.cjs +29 -0
- package/dist/context/MCPUIConfigContext.cjs.map +1 -0
- package/dist/context/MCPUIConfigContext.d.ts +124 -0
- package/dist/context/MCPUIConfigContext.d.ts.map +1 -0
- package/dist/context/MCPUIConfigContext.js +29 -0
- package/dist/context/MCPUIConfigContext.js.map +1 -0
- package/dist/context/MCPUIStringsContext.cjs +287 -2
- package/dist/context/MCPUIStringsContext.cjs.map +1 -1
- package/dist/context/MCPUIStringsContext.d.ts +607 -3
- package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
- package/dist/context/MCPUIStringsContext.js +287 -2
- package/dist/context/MCPUIStringsContext.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.cjs +28 -10
- package/dist/hooks/useStreamingUI.cjs.map +1 -1
- package/dist/hooks/useStreamingUI.d.ts +37 -0
- package/dist/hooks/useStreamingUI.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.js +28 -10
- package/dist/hooks/useStreamingUI.js.map +1 -1
- package/dist/hooks.cjs +1 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +2 -1
- package/dist/index.cjs +29 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/validation.cjs +52 -26
- package/dist/services/validation.cjs.map +1 -1
- package/dist/services/validation.d.ts +67 -2
- package/dist/services/validation.d.ts.map +1 -1
- package/dist/services/validation.js +52 -26
- package/dist/services/validation.js.map +1 -1
- package/dist/utils/degraded-projections.cjs +37 -12
- package/dist/utils/degraded-projections.cjs.map +1 -1
- package/dist/utils/degraded-projections.d.ts +39 -3
- package/dist/utils/degraded-projections.d.ts.map +1 -1
- package/dist/utils/degraded-projections.js +37 -12
- package/dist/utils/degraded-projections.js.map +1 -1
- package/dist/utils/format-string.cjs +10 -0
- package/dist/utils/format-string.cjs.map +1 -0
- package/dist/utils/format-string.d.ts +26 -0
- package/dist/utils/format-string.d.ts.map +1 -0
- package/dist/utils/format-string.js +10 -0
- package/dist/utils/format-string.js.map +1 -0
- package/dist/utils/iframe-coep.cjs +30 -0
- package/dist/utils/iframe-coep.cjs.map +1 -0
- package/dist/utils/iframe-coep.d.ts +46 -0
- package/dist/utils/iframe-coep.d.ts.map +1 -0
- package/dist/utils/iframe-coep.js +30 -0
- package/dist/utils/iframe-coep.js.map +1 -0
- package/dist/validation.cjs +5 -0
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.cts +2 -1
- package/dist/validation.d.ts +2 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +6 -1
- package/package.json +1 -1
- package/src/adapters/connector.ts +58 -4
- package/src/adapters/index.ts +12 -2
- package/src/adapters/macro-run.ts +71 -11
- package/src/components/ActionGroupRenderer.tsx +3 -1
- package/src/components/AgentCard.tsx +27 -9
- package/src/components/AgentHandoff.tsx +4 -1
- package/src/components/ArtifactRenderer.tsx +17 -5
- package/src/components/AutocompleteDropdown.tsx +8 -6
- package/src/components/AutocompleteFormField.tsx +5 -1
- package/src/components/BriefingDiff.tsx +11 -3
- package/src/components/CarouselRenderer.tsx +4 -2
- package/src/components/ChartJSRenderer.tsx +18 -9
- package/src/components/ChatPrompt.tsx +13 -8
- package/src/components/CodeBlockRenderer.tsx +12 -10
- package/src/components/DataPreviewSection.tsx +92 -26
- package/src/components/DegradedFallback.tsx +4 -2
- package/src/components/FooterRenderer.tsx +3 -1
- package/src/components/FormFieldRenderer.tsx +34 -19
- package/src/components/FormRenderer.tsx +38 -10
- package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
- package/src/components/GraphRenderer.tsx +31 -16
- package/src/components/IframeFallbackLink.tsx +57 -0
- package/src/components/ImageGalleryRenderer.tsx +8 -4
- package/src/components/LightboxOverlay.tsx +6 -4
- package/src/components/MapRenderer.tsx +57 -20
- package/src/components/ModalRenderer.tsx +3 -1
- package/src/components/ScratchpadPanel.tsx +95 -44
- package/src/components/StreamingUIRenderer.tsx +41 -11
- package/src/components/UIResourceRenderer.tsx +176 -67
- package/src/components/VerifiedText.tsx +19 -9
- package/src/components/VideoRenderer.tsx +26 -4
- package/src/components/chart-data-table.ts +68 -14
- package/src/context/MCPActionContext.tsx +4 -1
- package/src/context/MCPUIConfigContext.tsx +151 -0
- package/src/context/MCPUIStringsContext.tsx +1014 -1
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useStreamingUI.ts +64 -10
- package/src/index.ts +38 -0
- package/src/services/index.ts +1 -0
- package/src/services/validation.ts +131 -32
- package/src/solid-jsx-attrs.d.ts +24 -0
- package/src/utils/degraded-projections.ts +75 -12
- package/src/utils/format-string.ts +33 -0
- package/src/utils/iframe-coep.ts +74 -0
- package/src/validation.ts +9 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const web = require("solid-js/web");
|
|
4
4
|
const solidJs = require("solid-js");
|
|
5
|
+
const MCPUIStringsContext = require("./MCPUIStringsContext.cjs");
|
|
5
6
|
const MCPActionContext = solidJs.createContext();
|
|
6
7
|
const defaultExecutor = async (request) => {
|
|
7
8
|
return new Promise((resolve) => {
|
|
@@ -55,6 +56,7 @@ const defaultExecutor = async (request) => {
|
|
|
55
56
|
});
|
|
56
57
|
};
|
|
57
58
|
const MCPActionProvider = (props) => {
|
|
59
|
+
const strings = MCPUIStringsContext.useMCPUIStrings();
|
|
58
60
|
const [isExecuting, setIsExecuting] = solidJs.createSignal(false);
|
|
59
61
|
const [lastResult, setLastResult] = solidJs.createSignal();
|
|
60
62
|
const [spaceIds, _setSpaceIds] = solidJs.createSignal(props.spaceIds || []);
|
|
@@ -86,7 +88,7 @@ const MCPActionProvider = (props) => {
|
|
|
86
88
|
} catch (error) {
|
|
87
89
|
const errorResult = {
|
|
88
90
|
success: false,
|
|
89
|
-
error: error instanceof Error ? error.message :
|
|
91
|
+
error: error instanceof Error ? error.message : strings.errorUnknown,
|
|
90
92
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
91
93
|
toolName: request.toolName
|
|
92
94
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPActionContext.cjs","sources":["../../src/context/MCPActionContext.tsx"],"sourcesContent":["/**\n * MCPActionContext - Context provider for MCP action execution\n * Phase 5.0: Quick Wins - Replaces CustomEvent with typed context for Mastra integration\n */\n\nimport { createContext, createSignal, useContext, ParentComponent, Accessor } from 'solid-js'\n\n/**\n * Action request payload\n */\nexport interface ActionRequest {\n /**\n * MCP tool name to execute. For a `submit` action with no associated\n * tool, renderers pass the sentinel `'submit'` — branch on `action`,\n * not on `toolName`, to tell a submit apart from a tool call.\n */\n toolName: string\n\n /**\n * Tool parameters\n */\n params?: Record<string, any>\n\n /**\n * Optional space IDs for multi-space context\n */\n spaceIds?: string[]\n\n /**\n * Optional macro ID for template execution\n */\n macroId?: string\n\n /**\n * Action kind (v6.6.1). Lets a host `executor` tell a tool call apart\n * from a form-style `submit`. Absent ⇒ treat as `'tool-call'` (backward\n * compatible — every pre-v6.6.1 request omits it).\n *\n * A `submit` action carries its payload in `params` (e.g. `submit_url`,\n * `connector_id`, `feedback_value`) and **must NOT** be executed as a\n * tool call — the host routes it (e.g. POST to `params.submit_url`).\n */\n action?: 'tool-call' | 'submit' | 'link'\n}\n\n/**\n * Action result from execution\n */\nexport interface ActionResult {\n /**\n * Whether the action was successful\n */\n success: boolean\n\n /**\n * Result data (if successful)\n */\n data?: any\n\n /**\n * Error message (if failed)\n */\n error?: string\n\n /**\n * Execution timestamp\n */\n timestamp: string\n\n /**\n * Tool that was executed\n */\n toolName: string\n}\n\n/**\n * Context value interface\n */\nexport interface MCPActionContextValue {\n /**\n * Execute an MCP action\n */\n executeAction: (request: ActionRequest) => Promise<ActionResult>\n\n /**\n * Currently available tools (from MCP server)\n */\n availableTools: Accessor<string[]>\n\n /**\n * Space IDs in current context\n */\n spaceIds: Accessor<string[]>\n\n /**\n * Current macro ID (if executing within a template)\n */\n macroId: Accessor<string | undefined>\n\n /**\n * Whether an action is currently executing\n */\n isExecuting: Accessor<boolean>\n\n /**\n * Last action result\n */\n lastResult: Accessor<ActionResult | undefined>\n}\n\n/**\n * Props for MCPActionProvider\n */\nexport interface MCPActionProviderProps {\n /**\n * Space IDs for multi-space queries\n */\n spaceIds?: string[]\n\n /**\n * Macro ID when executing within a template\n */\n macroId?: string\n\n /**\n * Available MCP tools\n */\n availableTools?: string[]\n\n /**\n * Callback for action execution (for audit logging)\n */\n onAction?: (request: ActionRequest, result: ActionResult) => void\n\n /**\n * Callback for webhook events (n8n, Zapier integration)\n */\n onWebhook?: (event: { type: string; payload: any }) => void\n\n /**\n * Custom action executor (override default)\n */\n executor?: (request: ActionRequest) => Promise<ActionResult>\n}\n\n// Create the context with undefined default\nconst MCPActionContext = createContext<MCPActionContextValue>()\n\n/**\n * Default action executor using CustomEvent fallback\n * This maintains backward compatibility while allowing Context-based usage\n */\nconst defaultExecutor = async (request: ActionRequest): Promise<ActionResult> => {\n return new Promise((resolve) => {\n const timestamp = new Date().toISOString()\n\n // Dispatch CustomEvent for backward compatibility with existing listeners\n if (typeof window !== 'undefined') {\n const event = new CustomEvent('mcp-action', {\n detail: {\n toolName: request.toolName,\n params: request.params || {},\n spaceIds: request.spaceIds,\n macroId: request.macroId,\n // v6.6.1 — action kind so a window-level listener can route a\n // `submit` (POST to params.submit_url) vs a tool call.\n action: request.action ?? 'tool-call',\n },\n bubbles: true,\n })\n\n // Listen for response event\n const responseHandler = (e: Event) => {\n const customEvent = e as CustomEvent\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: customEvent.detail?.success ?? true,\n data: customEvent.detail?.data,\n error: customEvent.detail?.error,\n timestamp,\n toolName: request.toolName,\n })\n }\n\n window.addEventListener('mcp-action-response', responseHandler)\n window.dispatchEvent(event)\n\n // Timeout fallback - resolve as success if no response in 100ms\n // (indicates no listener, action was dispatched)\n setTimeout(() => {\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: true,\n data: { dispatched: true },\n timestamp,\n toolName: request.toolName,\n })\n }, 100)\n } else {\n // Server-side: return immediately\n resolve({\n success: false,\n error: 'Actions not available server-side',\n timestamp,\n toolName: request.toolName,\n })\n }\n })\n}\n\n/**\n * MCPActionProvider - Provides action execution context to child components\n *\n * @example\n * ```tsx\n * <MCPActionProvider\n * spaceIds={['space-123']}\n * macroId=\"sales_overview\"\n * onAction={(req, res) => audit(req, res)}\n * >\n * <UIResourceRenderer layout={layout} />\n * </MCPActionProvider>\n * ```\n */\nexport const MCPActionProvider: ParentComponent<MCPActionProviderProps> = (props) => {\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [spaceIds, _setSpaceIds] = createSignal<string[]>(props.spaceIds || [])\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [macroId, _setMacroId] = createSignal<string | undefined>(props.macroId)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [availableTools, _setAvailableTools] = createSignal<string[]>(props.availableTools || [])\n\n // Update signals when props change\n // Note: This is a simple approach; for more complex scenarios, consider createEffect\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n\n try {\n // Enrich request with context\n const enrichedRequest: ActionRequest = {\n ...request,\n spaceIds: request.spaceIds || spaceIds(),\n macroId: request.macroId || macroId(),\n }\n\n // Execute using custom executor or default\n const executor = props.executor || defaultExecutor\n const result = await executor(enrichedRequest)\n\n setLastResult(result)\n\n // Call audit callback if provided\n props.onAction?.(enrichedRequest, result)\n\n // Trigger webhook if provided and action was successful\n if (result.success && props.onWebhook) {\n props.onWebhook({\n type: 'action-completed',\n payload: {\n request: enrichedRequest,\n result,\n },\n })\n }\n\n return result\n } catch (error) {\n const errorResult: ActionResult = {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n timestamp: new Date().toISOString(),\n toolName: request.toolName,\n }\n\n setLastResult(errorResult)\n props.onAction?.(request, errorResult)\n\n return errorResult\n } finally {\n setIsExecuting(false)\n }\n }\n\n const contextValue: MCPActionContextValue = {\n executeAction,\n availableTools,\n spaceIds,\n macroId,\n isExecuting,\n lastResult,\n }\n\n return (\n <MCPActionContext.Provider value={contextValue}>\n {props.children}\n </MCPActionContext.Provider>\n )\n}\n\n/**\n * Hook to access MCP action context\n * Throws if used outside of MCPActionProvider\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPAction()\n *\n * const handleClick = async () => {\n * const result = await executeAction({\n * toolName: 'search.hub',\n * params: { query: 'revenue Q4' },\n * })\n * }\n * ```\n */\nexport function useMCPAction(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n if (!context) {\n throw new Error('useMCPAction must be used within an MCPActionProvider')\n }\n return context\n}\n\n/**\n * Hook to access MCP action context with fallback for components\n * outside of provider (uses CustomEvent fallback)\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPActionSafe()\n * // Works even without MCPActionProvider\n * ```\n */\nexport function useMCPActionSafe(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n\n if (context) {\n return context\n }\n\n // Fallback implementation for components outside provider\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n try {\n const result = await defaultExecutor(request)\n setLastResult(result)\n return result\n } finally {\n setIsExecuting(false)\n }\n }\n\n return {\n executeAction,\n availableTools: () => [],\n spaceIds: () => [],\n macroId: () => undefined,\n isExecuting,\n lastResult,\n }\n}\n\nexport { MCPActionContext }\n"],"names":["MCPActionContext","createContext","defaultExecutor","request","Promise","resolve","timestamp","Date","toISOString","window","event","CustomEvent","detail","toolName","params","spaceIds","macroId","action","bubbles","responseHandler","e","customEvent","removeEventListener","success","data","error","addEventListener","dispatchEvent","setTimeout","dispatched","MCPActionProvider","props","isExecuting","setIsExecuting","createSignal","lastResult","setLastResult","_setSpaceIds","_setMacroId","availableTools","_setAvailableTools","executeAction","enrichedRequest","executor","result","onAction","onWebhook","type","payload","errorResult","Error","message","contextValue","_$createComponent","Provider","value","children","useMCPAction","context","useContext","useMCPActionSafe","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MCPActionContext.cjs","sources":["../../src/context/MCPActionContext.tsx"],"sourcesContent":["/**\n * MCPActionContext - Context provider for MCP action execution\n * Phase 5.0: Quick Wins - Replaces CustomEvent with typed context for Mastra integration\n */\n\nimport { createContext, createSignal, useContext, ParentComponent, Accessor } from 'solid-js'\nimport { useMCPUIStrings } from './MCPUIStringsContext'\n\n/**\n * Action request payload\n */\nexport interface ActionRequest {\n /**\n * MCP tool name to execute. For a `submit` action with no associated\n * tool, renderers pass the sentinel `'submit'` — branch on `action`,\n * not on `toolName`, to tell a submit apart from a tool call.\n */\n toolName: string\n\n /**\n * Tool parameters\n */\n params?: Record<string, any>\n\n /**\n * Optional space IDs for multi-space context\n */\n spaceIds?: string[]\n\n /**\n * Optional macro ID for template execution\n */\n macroId?: string\n\n /**\n * Action kind (v6.6.1). Lets a host `executor` tell a tool call apart\n * from a form-style `submit`. Absent ⇒ treat as `'tool-call'` (backward\n * compatible — every pre-v6.6.1 request omits it).\n *\n * A `submit` action carries its payload in `params` (e.g. `submit_url`,\n * `connector_id`, `feedback_value`) and **must NOT** be executed as a\n * tool call — the host routes it (e.g. POST to `params.submit_url`).\n */\n action?: 'tool-call' | 'submit' | 'link'\n}\n\n/**\n * Action result from execution\n */\nexport interface ActionResult {\n /**\n * Whether the action was successful\n */\n success: boolean\n\n /**\n * Result data (if successful)\n */\n data?: any\n\n /**\n * Error message (if failed)\n */\n error?: string\n\n /**\n * Execution timestamp\n */\n timestamp: string\n\n /**\n * Tool that was executed\n */\n toolName: string\n}\n\n/**\n * Context value interface\n */\nexport interface MCPActionContextValue {\n /**\n * Execute an MCP action\n */\n executeAction: (request: ActionRequest) => Promise<ActionResult>\n\n /**\n * Currently available tools (from MCP server)\n */\n availableTools: Accessor<string[]>\n\n /**\n * Space IDs in current context\n */\n spaceIds: Accessor<string[]>\n\n /**\n * Current macro ID (if executing within a template)\n */\n macroId: Accessor<string | undefined>\n\n /**\n * Whether an action is currently executing\n */\n isExecuting: Accessor<boolean>\n\n /**\n * Last action result\n */\n lastResult: Accessor<ActionResult | undefined>\n}\n\n/**\n * Props for MCPActionProvider\n */\nexport interface MCPActionProviderProps {\n /**\n * Space IDs for multi-space queries\n */\n spaceIds?: string[]\n\n /**\n * Macro ID when executing within a template\n */\n macroId?: string\n\n /**\n * Available MCP tools\n */\n availableTools?: string[]\n\n /**\n * Callback for action execution (for audit logging)\n */\n onAction?: (request: ActionRequest, result: ActionResult) => void\n\n /**\n * Callback for webhook events (n8n, Zapier integration)\n */\n onWebhook?: (event: { type: string; payload: any }) => void\n\n /**\n * Custom action executor (override default)\n */\n executor?: (request: ActionRequest) => Promise<ActionResult>\n}\n\n// Create the context with undefined default\nconst MCPActionContext = createContext<MCPActionContextValue>()\n\n/**\n * Default action executor using CustomEvent fallback\n * This maintains backward compatibility while allowing Context-based usage\n */\nconst defaultExecutor = async (request: ActionRequest): Promise<ActionResult> => {\n return new Promise((resolve) => {\n const timestamp = new Date().toISOString()\n\n // Dispatch CustomEvent for backward compatibility with existing listeners\n if (typeof window !== 'undefined') {\n const event = new CustomEvent('mcp-action', {\n detail: {\n toolName: request.toolName,\n params: request.params || {},\n spaceIds: request.spaceIds,\n macroId: request.macroId,\n // v6.6.1 — action kind so a window-level listener can route a\n // `submit` (POST to params.submit_url) vs a tool call.\n action: request.action ?? 'tool-call',\n },\n bubbles: true,\n })\n\n // Listen for response event\n const responseHandler = (e: Event) => {\n const customEvent = e as CustomEvent\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: customEvent.detail?.success ?? true,\n data: customEvent.detail?.data,\n error: customEvent.detail?.error,\n timestamp,\n toolName: request.toolName,\n })\n }\n\n window.addEventListener('mcp-action-response', responseHandler)\n window.dispatchEvent(event)\n\n // Timeout fallback - resolve as success if no response in 100ms\n // (indicates no listener, action was dispatched)\n setTimeout(() => {\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: true,\n data: { dispatched: true },\n timestamp,\n toolName: request.toolName,\n })\n }, 100)\n } else {\n // Server-side: return immediately\n resolve({\n success: false,\n error: 'Actions not available server-side',\n timestamp,\n toolName: request.toolName,\n })\n }\n })\n}\n\n/**\n * MCPActionProvider - Provides action execution context to child components\n *\n * @example\n * ```tsx\n * <MCPActionProvider\n * spaceIds={['space-123']}\n * macroId=\"sales_overview\"\n * onAction={(req, res) => audit(req, res)}\n * >\n * <UIResourceRenderer layout={layout} />\n * </MCPActionProvider>\n * ```\n */\nexport const MCPActionProvider: ParentComponent<MCPActionProviderProps> = (props) => {\n // The error of a failed action can be rendered by FormRenderer.\n const strings = useMCPUIStrings()\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [spaceIds, _setSpaceIds] = createSignal<string[]>(props.spaceIds || [])\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [macroId, _setMacroId] = createSignal<string | undefined>(props.macroId)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [availableTools, _setAvailableTools] = createSignal<string[]>(props.availableTools || [])\n\n // Update signals when props change\n // Note: This is a simple approach; for more complex scenarios, consider createEffect\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n\n try {\n // Enrich request with context\n const enrichedRequest: ActionRequest = {\n ...request,\n spaceIds: request.spaceIds || spaceIds(),\n macroId: request.macroId || macroId(),\n }\n\n // Execute using custom executor or default\n const executor = props.executor || defaultExecutor\n const result = await executor(enrichedRequest)\n\n setLastResult(result)\n\n // Call audit callback if provided\n props.onAction?.(enrichedRequest, result)\n\n // Trigger webhook if provided and action was successful\n if (result.success && props.onWebhook) {\n props.onWebhook({\n type: 'action-completed',\n payload: {\n request: enrichedRequest,\n result,\n },\n })\n }\n\n return result\n } catch (error) {\n const errorResult: ActionResult = {\n success: false,\n error: error instanceof Error ? error.message : strings.errorUnknown,\n timestamp: new Date().toISOString(),\n toolName: request.toolName,\n }\n\n setLastResult(errorResult)\n props.onAction?.(request, errorResult)\n\n return errorResult\n } finally {\n setIsExecuting(false)\n }\n }\n\n const contextValue: MCPActionContextValue = {\n executeAction,\n availableTools,\n spaceIds,\n macroId,\n isExecuting,\n lastResult,\n }\n\n return (\n <MCPActionContext.Provider value={contextValue}>\n {props.children}\n </MCPActionContext.Provider>\n )\n}\n\n/**\n * Hook to access MCP action context\n * Throws if used outside of MCPActionProvider\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPAction()\n *\n * const handleClick = async () => {\n * const result = await executeAction({\n * toolName: 'search.hub',\n * params: { query: 'revenue Q4' },\n * })\n * }\n * ```\n */\nexport function useMCPAction(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n if (!context) {\n throw new Error('useMCPAction must be used within an MCPActionProvider')\n }\n return context\n}\n\n/**\n * Hook to access MCP action context with fallback for components\n * outside of provider (uses CustomEvent fallback)\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPActionSafe()\n * // Works even without MCPActionProvider\n * ```\n */\nexport function useMCPActionSafe(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n\n if (context) {\n return context\n }\n\n // Fallback implementation for components outside provider\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n try {\n const result = await defaultExecutor(request)\n setLastResult(result)\n return result\n } finally {\n setIsExecuting(false)\n }\n }\n\n return {\n executeAction,\n availableTools: () => [],\n spaceIds: () => [],\n macroId: () => undefined,\n isExecuting,\n lastResult,\n }\n}\n\nexport { MCPActionContext }\n"],"names":["MCPActionContext","createContext","defaultExecutor","request","Promise","resolve","timestamp","Date","toISOString","window","event","CustomEvent","detail","toolName","params","spaceIds","macroId","action","bubbles","responseHandler","e","customEvent","removeEventListener","success","data","error","addEventListener","dispatchEvent","setTimeout","dispatched","MCPActionProvider","props","strings","useMCPUIStrings","isExecuting","setIsExecuting","createSignal","lastResult","setLastResult","_setSpaceIds","_setMacroId","availableTools","_setAvailableTools","executeAction","enrichedRequest","executor","result","onAction","onWebhook","type","payload","errorResult","Error","message","errorUnknown","contextValue","_$createComponent","Provider","value","children","useMCPAction","context","useContext","useMCPActionSafe","undefined"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPActionContext.d.ts","sourceRoot":"","sources":["../../src/context/MCPActionContext.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA2C,eAAe,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"MCPActionContext.d.ts","sourceRoot":"","sources":["../../src/context/MCPActionContext.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA2C,eAAe,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAG7F;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE5B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAA;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAA;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,GAAG,CAAA;IAEV;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,aAAa,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAEhE;;OAEG;IACH,cAAc,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAElC;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAE5B;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAErC;;OAEG;IACH,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAE9B;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,YAAY,GAAG,SAAS,CAAC,CAAA;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,CAAA;IAEjE;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,CAAA;IAE3D;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;CAC7D;AAGD,QAAA,MAAM,gBAAgB,+DAAyC,CAAA;AAgE/D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,eAAe,CAAC,sBAAsB,CA8ErE,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,IAAI,qBAAqB,CAMpD;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,IAAI,qBAAqB,CA8BxD;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createComponent } from "solid-js/web";
|
|
2
2
|
import { createContext, createSignal, useContext } from "solid-js";
|
|
3
|
+
import { useMCPUIStrings } from "./MCPUIStringsContext.js";
|
|
3
4
|
const MCPActionContext = createContext();
|
|
4
5
|
const defaultExecutor = async (request) => {
|
|
5
6
|
return new Promise((resolve) => {
|
|
@@ -53,6 +54,7 @@ const defaultExecutor = async (request) => {
|
|
|
53
54
|
});
|
|
54
55
|
};
|
|
55
56
|
const MCPActionProvider = (props) => {
|
|
57
|
+
const strings = useMCPUIStrings();
|
|
56
58
|
const [isExecuting, setIsExecuting] = createSignal(false);
|
|
57
59
|
const [lastResult, setLastResult] = createSignal();
|
|
58
60
|
const [spaceIds, _setSpaceIds] = createSignal(props.spaceIds || []);
|
|
@@ -84,7 +86,7 @@ const MCPActionProvider = (props) => {
|
|
|
84
86
|
} catch (error) {
|
|
85
87
|
const errorResult = {
|
|
86
88
|
success: false,
|
|
87
|
-
error: error instanceof Error ? error.message :
|
|
89
|
+
error: error instanceof Error ? error.message : strings.errorUnknown,
|
|
88
90
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
89
91
|
toolName: request.toolName
|
|
90
92
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPActionContext.js","sources":["../../src/context/MCPActionContext.tsx"],"sourcesContent":["/**\n * MCPActionContext - Context provider for MCP action execution\n * Phase 5.0: Quick Wins - Replaces CustomEvent with typed context for Mastra integration\n */\n\nimport { createContext, createSignal, useContext, ParentComponent, Accessor } from 'solid-js'\n\n/**\n * Action request payload\n */\nexport interface ActionRequest {\n /**\n * MCP tool name to execute. For a `submit` action with no associated\n * tool, renderers pass the sentinel `'submit'` — branch on `action`,\n * not on `toolName`, to tell a submit apart from a tool call.\n */\n toolName: string\n\n /**\n * Tool parameters\n */\n params?: Record<string, any>\n\n /**\n * Optional space IDs for multi-space context\n */\n spaceIds?: string[]\n\n /**\n * Optional macro ID for template execution\n */\n macroId?: string\n\n /**\n * Action kind (v6.6.1). Lets a host `executor` tell a tool call apart\n * from a form-style `submit`. Absent ⇒ treat as `'tool-call'` (backward\n * compatible — every pre-v6.6.1 request omits it).\n *\n * A `submit` action carries its payload in `params` (e.g. `submit_url`,\n * `connector_id`, `feedback_value`) and **must NOT** be executed as a\n * tool call — the host routes it (e.g. POST to `params.submit_url`).\n */\n action?: 'tool-call' | 'submit' | 'link'\n}\n\n/**\n * Action result from execution\n */\nexport interface ActionResult {\n /**\n * Whether the action was successful\n */\n success: boolean\n\n /**\n * Result data (if successful)\n */\n data?: any\n\n /**\n * Error message (if failed)\n */\n error?: string\n\n /**\n * Execution timestamp\n */\n timestamp: string\n\n /**\n * Tool that was executed\n */\n toolName: string\n}\n\n/**\n * Context value interface\n */\nexport interface MCPActionContextValue {\n /**\n * Execute an MCP action\n */\n executeAction: (request: ActionRequest) => Promise<ActionResult>\n\n /**\n * Currently available tools (from MCP server)\n */\n availableTools: Accessor<string[]>\n\n /**\n * Space IDs in current context\n */\n spaceIds: Accessor<string[]>\n\n /**\n * Current macro ID (if executing within a template)\n */\n macroId: Accessor<string | undefined>\n\n /**\n * Whether an action is currently executing\n */\n isExecuting: Accessor<boolean>\n\n /**\n * Last action result\n */\n lastResult: Accessor<ActionResult | undefined>\n}\n\n/**\n * Props for MCPActionProvider\n */\nexport interface MCPActionProviderProps {\n /**\n * Space IDs for multi-space queries\n */\n spaceIds?: string[]\n\n /**\n * Macro ID when executing within a template\n */\n macroId?: string\n\n /**\n * Available MCP tools\n */\n availableTools?: string[]\n\n /**\n * Callback for action execution (for audit logging)\n */\n onAction?: (request: ActionRequest, result: ActionResult) => void\n\n /**\n * Callback for webhook events (n8n, Zapier integration)\n */\n onWebhook?: (event: { type: string; payload: any }) => void\n\n /**\n * Custom action executor (override default)\n */\n executor?: (request: ActionRequest) => Promise<ActionResult>\n}\n\n// Create the context with undefined default\nconst MCPActionContext = createContext<MCPActionContextValue>()\n\n/**\n * Default action executor using CustomEvent fallback\n * This maintains backward compatibility while allowing Context-based usage\n */\nconst defaultExecutor = async (request: ActionRequest): Promise<ActionResult> => {\n return new Promise((resolve) => {\n const timestamp = new Date().toISOString()\n\n // Dispatch CustomEvent for backward compatibility with existing listeners\n if (typeof window !== 'undefined') {\n const event = new CustomEvent('mcp-action', {\n detail: {\n toolName: request.toolName,\n params: request.params || {},\n spaceIds: request.spaceIds,\n macroId: request.macroId,\n // v6.6.1 — action kind so a window-level listener can route a\n // `submit` (POST to params.submit_url) vs a tool call.\n action: request.action ?? 'tool-call',\n },\n bubbles: true,\n })\n\n // Listen for response event\n const responseHandler = (e: Event) => {\n const customEvent = e as CustomEvent\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: customEvent.detail?.success ?? true,\n data: customEvent.detail?.data,\n error: customEvent.detail?.error,\n timestamp,\n toolName: request.toolName,\n })\n }\n\n window.addEventListener('mcp-action-response', responseHandler)\n window.dispatchEvent(event)\n\n // Timeout fallback - resolve as success if no response in 100ms\n // (indicates no listener, action was dispatched)\n setTimeout(() => {\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: true,\n data: { dispatched: true },\n timestamp,\n toolName: request.toolName,\n })\n }, 100)\n } else {\n // Server-side: return immediately\n resolve({\n success: false,\n error: 'Actions not available server-side',\n timestamp,\n toolName: request.toolName,\n })\n }\n })\n}\n\n/**\n * MCPActionProvider - Provides action execution context to child components\n *\n * @example\n * ```tsx\n * <MCPActionProvider\n * spaceIds={['space-123']}\n * macroId=\"sales_overview\"\n * onAction={(req, res) => audit(req, res)}\n * >\n * <UIResourceRenderer layout={layout} />\n * </MCPActionProvider>\n * ```\n */\nexport const MCPActionProvider: ParentComponent<MCPActionProviderProps> = (props) => {\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [spaceIds, _setSpaceIds] = createSignal<string[]>(props.spaceIds || [])\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [macroId, _setMacroId] = createSignal<string | undefined>(props.macroId)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [availableTools, _setAvailableTools] = createSignal<string[]>(props.availableTools || [])\n\n // Update signals when props change\n // Note: This is a simple approach; for more complex scenarios, consider createEffect\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n\n try {\n // Enrich request with context\n const enrichedRequest: ActionRequest = {\n ...request,\n spaceIds: request.spaceIds || spaceIds(),\n macroId: request.macroId || macroId(),\n }\n\n // Execute using custom executor or default\n const executor = props.executor || defaultExecutor\n const result = await executor(enrichedRequest)\n\n setLastResult(result)\n\n // Call audit callback if provided\n props.onAction?.(enrichedRequest, result)\n\n // Trigger webhook if provided and action was successful\n if (result.success && props.onWebhook) {\n props.onWebhook({\n type: 'action-completed',\n payload: {\n request: enrichedRequest,\n result,\n },\n })\n }\n\n return result\n } catch (error) {\n const errorResult: ActionResult = {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n timestamp: new Date().toISOString(),\n toolName: request.toolName,\n }\n\n setLastResult(errorResult)\n props.onAction?.(request, errorResult)\n\n return errorResult\n } finally {\n setIsExecuting(false)\n }\n }\n\n const contextValue: MCPActionContextValue = {\n executeAction,\n availableTools,\n spaceIds,\n macroId,\n isExecuting,\n lastResult,\n }\n\n return (\n <MCPActionContext.Provider value={contextValue}>\n {props.children}\n </MCPActionContext.Provider>\n )\n}\n\n/**\n * Hook to access MCP action context\n * Throws if used outside of MCPActionProvider\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPAction()\n *\n * const handleClick = async () => {\n * const result = await executeAction({\n * toolName: 'search.hub',\n * params: { query: 'revenue Q4' },\n * })\n * }\n * ```\n */\nexport function useMCPAction(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n if (!context) {\n throw new Error('useMCPAction must be used within an MCPActionProvider')\n }\n return context\n}\n\n/**\n * Hook to access MCP action context with fallback for components\n * outside of provider (uses CustomEvent fallback)\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPActionSafe()\n * // Works even without MCPActionProvider\n * ```\n */\nexport function useMCPActionSafe(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n\n if (context) {\n return context\n }\n\n // Fallback implementation for components outside provider\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n try {\n const result = await defaultExecutor(request)\n setLastResult(result)\n return result\n } finally {\n setIsExecuting(false)\n }\n }\n\n return {\n executeAction,\n availableTools: () => [],\n spaceIds: () => [],\n macroId: () => undefined,\n isExecuting,\n lastResult,\n }\n}\n\nexport { MCPActionContext }\n"],"names":["MCPActionContext","createContext","defaultExecutor","request","Promise","resolve","timestamp","Date","toISOString","window","event","CustomEvent","detail","toolName","params","spaceIds","macroId","action","bubbles","responseHandler","e","customEvent","removeEventListener","success","data","error","addEventListener","dispatchEvent","setTimeout","dispatched","MCPActionProvider","props","isExecuting","setIsExecuting","createSignal","lastResult","setLastResult","_setSpaceIds","_setMacroId","availableTools","_setAvailableTools","executeAction","enrichedRequest","executor","result","onAction","onWebhook","type","payload","errorResult","Error","message","contextValue","_$createComponent","Provider","value","children","useMCPAction","context","useContext","useMCPActionSafe","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MCPActionContext.js","sources":["../../src/context/MCPActionContext.tsx"],"sourcesContent":["/**\n * MCPActionContext - Context provider for MCP action execution\n * Phase 5.0: Quick Wins - Replaces CustomEvent with typed context for Mastra integration\n */\n\nimport { createContext, createSignal, useContext, ParentComponent, Accessor } from 'solid-js'\nimport { useMCPUIStrings } from './MCPUIStringsContext'\n\n/**\n * Action request payload\n */\nexport interface ActionRequest {\n /**\n * MCP tool name to execute. For a `submit` action with no associated\n * tool, renderers pass the sentinel `'submit'` — branch on `action`,\n * not on `toolName`, to tell a submit apart from a tool call.\n */\n toolName: string\n\n /**\n * Tool parameters\n */\n params?: Record<string, any>\n\n /**\n * Optional space IDs for multi-space context\n */\n spaceIds?: string[]\n\n /**\n * Optional macro ID for template execution\n */\n macroId?: string\n\n /**\n * Action kind (v6.6.1). Lets a host `executor` tell a tool call apart\n * from a form-style `submit`. Absent ⇒ treat as `'tool-call'` (backward\n * compatible — every pre-v6.6.1 request omits it).\n *\n * A `submit` action carries its payload in `params` (e.g. `submit_url`,\n * `connector_id`, `feedback_value`) and **must NOT** be executed as a\n * tool call — the host routes it (e.g. POST to `params.submit_url`).\n */\n action?: 'tool-call' | 'submit' | 'link'\n}\n\n/**\n * Action result from execution\n */\nexport interface ActionResult {\n /**\n * Whether the action was successful\n */\n success: boolean\n\n /**\n * Result data (if successful)\n */\n data?: any\n\n /**\n * Error message (if failed)\n */\n error?: string\n\n /**\n * Execution timestamp\n */\n timestamp: string\n\n /**\n * Tool that was executed\n */\n toolName: string\n}\n\n/**\n * Context value interface\n */\nexport interface MCPActionContextValue {\n /**\n * Execute an MCP action\n */\n executeAction: (request: ActionRequest) => Promise<ActionResult>\n\n /**\n * Currently available tools (from MCP server)\n */\n availableTools: Accessor<string[]>\n\n /**\n * Space IDs in current context\n */\n spaceIds: Accessor<string[]>\n\n /**\n * Current macro ID (if executing within a template)\n */\n macroId: Accessor<string | undefined>\n\n /**\n * Whether an action is currently executing\n */\n isExecuting: Accessor<boolean>\n\n /**\n * Last action result\n */\n lastResult: Accessor<ActionResult | undefined>\n}\n\n/**\n * Props for MCPActionProvider\n */\nexport interface MCPActionProviderProps {\n /**\n * Space IDs for multi-space queries\n */\n spaceIds?: string[]\n\n /**\n * Macro ID when executing within a template\n */\n macroId?: string\n\n /**\n * Available MCP tools\n */\n availableTools?: string[]\n\n /**\n * Callback for action execution (for audit logging)\n */\n onAction?: (request: ActionRequest, result: ActionResult) => void\n\n /**\n * Callback for webhook events (n8n, Zapier integration)\n */\n onWebhook?: (event: { type: string; payload: any }) => void\n\n /**\n * Custom action executor (override default)\n */\n executor?: (request: ActionRequest) => Promise<ActionResult>\n}\n\n// Create the context with undefined default\nconst MCPActionContext = createContext<MCPActionContextValue>()\n\n/**\n * Default action executor using CustomEvent fallback\n * This maintains backward compatibility while allowing Context-based usage\n */\nconst defaultExecutor = async (request: ActionRequest): Promise<ActionResult> => {\n return new Promise((resolve) => {\n const timestamp = new Date().toISOString()\n\n // Dispatch CustomEvent for backward compatibility with existing listeners\n if (typeof window !== 'undefined') {\n const event = new CustomEvent('mcp-action', {\n detail: {\n toolName: request.toolName,\n params: request.params || {},\n spaceIds: request.spaceIds,\n macroId: request.macroId,\n // v6.6.1 — action kind so a window-level listener can route a\n // `submit` (POST to params.submit_url) vs a tool call.\n action: request.action ?? 'tool-call',\n },\n bubbles: true,\n })\n\n // Listen for response event\n const responseHandler = (e: Event) => {\n const customEvent = e as CustomEvent\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: customEvent.detail?.success ?? true,\n data: customEvent.detail?.data,\n error: customEvent.detail?.error,\n timestamp,\n toolName: request.toolName,\n })\n }\n\n window.addEventListener('mcp-action-response', responseHandler)\n window.dispatchEvent(event)\n\n // Timeout fallback - resolve as success if no response in 100ms\n // (indicates no listener, action was dispatched)\n setTimeout(() => {\n window.removeEventListener('mcp-action-response', responseHandler)\n resolve({\n success: true,\n data: { dispatched: true },\n timestamp,\n toolName: request.toolName,\n })\n }, 100)\n } else {\n // Server-side: return immediately\n resolve({\n success: false,\n error: 'Actions not available server-side',\n timestamp,\n toolName: request.toolName,\n })\n }\n })\n}\n\n/**\n * MCPActionProvider - Provides action execution context to child components\n *\n * @example\n * ```tsx\n * <MCPActionProvider\n * spaceIds={['space-123']}\n * macroId=\"sales_overview\"\n * onAction={(req, res) => audit(req, res)}\n * >\n * <UIResourceRenderer layout={layout} />\n * </MCPActionProvider>\n * ```\n */\nexport const MCPActionProvider: ParentComponent<MCPActionProviderProps> = (props) => {\n // The error of a failed action can be rendered by FormRenderer.\n const strings = useMCPUIStrings()\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [spaceIds, _setSpaceIds] = createSignal<string[]>(props.spaceIds || [])\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [macroId, _setMacroId] = createSignal<string | undefined>(props.macroId)\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [availableTools, _setAvailableTools] = createSignal<string[]>(props.availableTools || [])\n\n // Update signals when props change\n // Note: This is a simple approach; for more complex scenarios, consider createEffect\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n\n try {\n // Enrich request with context\n const enrichedRequest: ActionRequest = {\n ...request,\n spaceIds: request.spaceIds || spaceIds(),\n macroId: request.macroId || macroId(),\n }\n\n // Execute using custom executor or default\n const executor = props.executor || defaultExecutor\n const result = await executor(enrichedRequest)\n\n setLastResult(result)\n\n // Call audit callback if provided\n props.onAction?.(enrichedRequest, result)\n\n // Trigger webhook if provided and action was successful\n if (result.success && props.onWebhook) {\n props.onWebhook({\n type: 'action-completed',\n payload: {\n request: enrichedRequest,\n result,\n },\n })\n }\n\n return result\n } catch (error) {\n const errorResult: ActionResult = {\n success: false,\n error: error instanceof Error ? error.message : strings.errorUnknown,\n timestamp: new Date().toISOString(),\n toolName: request.toolName,\n }\n\n setLastResult(errorResult)\n props.onAction?.(request, errorResult)\n\n return errorResult\n } finally {\n setIsExecuting(false)\n }\n }\n\n const contextValue: MCPActionContextValue = {\n executeAction,\n availableTools,\n spaceIds,\n macroId,\n isExecuting,\n lastResult,\n }\n\n return (\n <MCPActionContext.Provider value={contextValue}>\n {props.children}\n </MCPActionContext.Provider>\n )\n}\n\n/**\n * Hook to access MCP action context\n * Throws if used outside of MCPActionProvider\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPAction()\n *\n * const handleClick = async () => {\n * const result = await executeAction({\n * toolName: 'search.hub',\n * params: { query: 'revenue Q4' },\n * })\n * }\n * ```\n */\nexport function useMCPAction(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n if (!context) {\n throw new Error('useMCPAction must be used within an MCPActionProvider')\n }\n return context\n}\n\n/**\n * Hook to access MCP action context with fallback for components\n * outside of provider (uses CustomEvent fallback)\n *\n * @example\n * ```tsx\n * const { executeAction, isExecuting } = useMCPActionSafe()\n * // Works even without MCPActionProvider\n * ```\n */\nexport function useMCPActionSafe(): MCPActionContextValue {\n const context = useContext(MCPActionContext)\n\n if (context) {\n return context\n }\n\n // Fallback implementation for components outside provider\n const [isExecuting, setIsExecuting] = createSignal(false)\n const [lastResult, setLastResult] = createSignal<ActionResult>()\n\n const executeAction = async (request: ActionRequest): Promise<ActionResult> => {\n setIsExecuting(true)\n try {\n const result = await defaultExecutor(request)\n setLastResult(result)\n return result\n } finally {\n setIsExecuting(false)\n }\n }\n\n return {\n executeAction,\n availableTools: () => [],\n spaceIds: () => [],\n macroId: () => undefined,\n isExecuting,\n lastResult,\n }\n}\n\nexport { MCPActionContext }\n"],"names":["MCPActionContext","createContext","defaultExecutor","request","Promise","resolve","timestamp","Date","toISOString","window","event","CustomEvent","detail","toolName","params","spaceIds","macroId","action","bubbles","responseHandler","e","customEvent","removeEventListener","success","data","error","addEventListener","dispatchEvent","setTimeout","dispatched","MCPActionProvider","props","strings","useMCPUIStrings","isExecuting","setIsExecuting","createSignal","lastResult","setLastResult","_setSpaceIds","_setMacroId","availableTools","_setAvailableTools","executeAction","enrichedRequest","executor","result","onAction","onWebhook","type","payload","errorResult","Error","message","errorUnknown","contextValue","_$createComponent","Provider","value","children","useMCPAction","context","useContext","useMCPActionSafe","undefined"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const web = require("solid-js/web");
|
|
4
|
+
const solidJs = require("solid-js");
|
|
5
|
+
const DEFAULT_MCPUI_CONFIG = {
|
|
6
|
+
iframeCredentialless: "auto",
|
|
7
|
+
customTrustedIframeDomains: [],
|
|
8
|
+
iframePolicy: "strict",
|
|
9
|
+
customIframeDomains: [],
|
|
10
|
+
iframeFallbackLink: "auto"
|
|
11
|
+
};
|
|
12
|
+
const MCPUIConfigContext = solidJs.createContext(DEFAULT_MCPUI_CONFIG);
|
|
13
|
+
function useMCPUIConfig() {
|
|
14
|
+
return solidJs.mergeProps(DEFAULT_MCPUI_CONFIG, solidJs.useContext(MCPUIConfigContext));
|
|
15
|
+
}
|
|
16
|
+
function MCPUIConfigProvider(props) {
|
|
17
|
+
const value = solidJs.mergeProps(DEFAULT_MCPUI_CONFIG, () => props.config);
|
|
18
|
+
return web.createComponent(MCPUIConfigContext.Provider, {
|
|
19
|
+
value,
|
|
20
|
+
get children() {
|
|
21
|
+
return props.children;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
exports.DEFAULT_MCPUI_CONFIG = DEFAULT_MCPUI_CONFIG;
|
|
26
|
+
exports.MCPUIConfigContext = MCPUIConfigContext;
|
|
27
|
+
exports.MCPUIConfigProvider = MCPUIConfigProvider;
|
|
28
|
+
exports.useMCPUIConfig = useMCPUIConfig;
|
|
29
|
+
//# sourceMappingURL=MCPUIConfigContext.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MCPUIConfigContext.cjs","sources":["../../src/context/MCPUIConfigContext.tsx"],"sourcesContent":["/**\n * MCPUIConfigContext — host-level rendering policy for the library's iframes.\n *\n * @since v6.21.0\n *\n * ## Why\n *\n * A host that serves `Cross-Origin-Embedder-Policy: credentialless` makes the\n * browser refuse every cross-origin iframe whose own document does not send a\n * COEP header — which is YouTube, Vimeo, Google Docs, Notion and nearly all of\n * `DEFAULT_IFRAME_DOMAINS`. The escape hatch is the boolean HTML attribute\n * `credentialless` on the `<iframe>` itself: the document then loads, but\n * without access to the cookies and storage of its own origin.\n *\n * That trade-off is free for a public video or chart and fatal for an\n * authenticated embed, so the library keys it on the distinction it already\n * makes: `TRUSTED_IFRAME_DOMAINS` (the hosts that receive `allow-same-origin`\n * because they need their own cookies) do NOT get the attribute; everything\n * else does. This context lets a host override that, add its own trusted\n * hosts, and control the \"open in a new tab\" fallback link.\n *\n * ## Scope — policy only, NOT strings\n *\n * Text lives in `MCPUIStrings` (`MCPUIStringsContext`). This context carries\n * only behavioural switches, and like the strings context every renderer works\n * standalone: with no provider mounted, `DEFAULT_MCPUI_CONFIG` applies.\n *\n * @example\n * ```tsx\n * import { MCPUIConfigProvider } from '@seed-ship/mcp-ui-solid'\n *\n * <MCPUIConfigProvider config={{ customTrustedIframeDomains: ['embed.acme.com'] }}>\n * <App />\n * </MCPUIConfigProvider>\n * ```\n */\n\nimport { createContext, mergeProps, useContext, type JSX } from 'solid-js'\nimport type { IframePolicy } from '../types'\n\n/**\n * Host-level rendering policy. Every field has a default — a provider passes\n * a partial override.\n */\nexport interface MCPUIConfig {\n /**\n * When the library puts the boolean `credentialless` attribute on an\n * `<iframe>` it renders.\n *\n * - `'auto'` (default) — on every iframe whose host is NOT in\n * `TRUSTED_IFRAME_DOMAINS` (plus `customTrustedIframeDomains`). Those\n * hosts already ran without cookies, since their sandbox has no\n * `allow-same-origin`; the attribute is what unblocks them under COEP.\n * - `'always'` — on every iframe, trusted hosts included. An authenticated\n * embed will then render its login screen.\n * - `'never'` — never. The right value for a host that sends no COEP header\n * and does not want its embeds to lose their cookies.\n *\n * Chrome/Edge 110+ honour the attribute; Firefox ignores it (iframes stay\n * blocked while the host sends COEP); Safari ignores the COEP value itself,\n * so nothing is blocked there in the first place.\n */\n iframeCredentialless: 'auto' | 'always' | 'never'\n\n /**\n * Extra hosts treated as trusted, on top of `TRUSTED_IFRAME_DOMAINS`:\n * no `credentialless` attribute, and `allow-same-origin` in the sandbox.\n * A subdomain of a listed host matches too.\n *\n * This only RECLASSIFIES a host the allow-list already accepts. To render an\n * iframe whose host is outside `DEFAULT_IFRAME_DOMAINS`, add it to\n * {@link MCPUIConfig.customIframeDomains} with `iframePolicy: 'extend'`.\n */\n customTrustedIframeDomains: string[]\n\n /**\n * How `UIResourceRenderer` validates an `iframe` component's host:\n * `'strict'` (default) accepts `DEFAULT_IFRAME_DOMAINS` only, `'extend'`\n * also accepts {@link MCPUIConfig.customIframeDomains}.\n */\n iframePolicy: IframePolicy\n\n /**\n * Extra hosts the allow-list accepts when `iframePolicy` is `'extend'`.\n * Without this, a component pointing at an unlisted host is replaced by the\n * validation card before any renderer runs.\n */\n customIframeDomains: string[]\n\n /**\n * When the library renders an \"open in a new tab\" link under an embed\n * (`strings.iframeOpenInNewTab`).\n *\n * A COEP-blocked iframe fires no event the parent page can observe, so\n * without this the user sees an unexplained blank frame.\n *\n * - `'auto'` (default) — only when the page is cross-origin isolated\n * (`window.crossOriginIsolated`). That flag needs COOP `same-origin` AND\n * COEP, so a host that sends COEP alone still blocks embeds while the\n * flag is false: set `'always'` there. Read after mount, never during\n * render, so SSR markup and hydration agree.\n * - `'always'` / `'never'` — unconditional.\n */\n iframeFallbackLink: 'auto' | 'always' | 'never'\n}\n\n/**\n * Defaults. Chosen so a host that sends no COEP header sees no change from\n * 6.20.0 apart from the fallback link, which `'auto'` keeps hidden there.\n */\nexport const DEFAULT_MCPUI_CONFIG: MCPUIConfig = {\n iframeCredentialless: 'auto',\n customTrustedIframeDomains: [],\n iframePolicy: 'strict',\n customIframeDomains: [],\n iframeFallbackLink: 'auto',\n}\n\nexport const MCPUIConfigContext = createContext<MCPUIConfig>(DEFAULT_MCPUI_CONFIG)\n\n/**\n * Reads the active host config. Returns `DEFAULT_MCPUI_CONFIG` when no\n * `<MCPUIConfigProvider>` is mounted above.\n */\nexport function useMCPUIConfig(): MCPUIConfig {\n return mergeProps(DEFAULT_MCPUI_CONFIG, useContext(MCPUIConfigContext))\n}\n\nexport interface MCPUIConfigProviderProps {\n /**\n * Partial override of the host config. Any key left unset falls back to\n * `DEFAULT_MCPUI_CONFIG`.\n */\n config?: Partial<MCPUIConfig>\n children: JSX.Element\n}\n\n/**\n * Provides the host config to every MCP-UI renderer below it.\n * Merges the partial `config` override over the defaults.\n */\nexport function MCPUIConfigProvider(props: MCPUIConfigProviderProps): JSX.Element {\n // The function source keeps replacement `config` objects reactive while\n // mergeProps fills any omitted key without taking a one-time snapshot.\n const value = mergeProps(DEFAULT_MCPUI_CONFIG, () => props.config)\n return (\n <MCPUIConfigContext.Provider value={value}>\n {props.children}\n </MCPUIConfigContext.Provider>\n )\n}\n"],"names":["DEFAULT_MCPUI_CONFIG","iframeCredentialless","customTrustedIframeDomains","iframePolicy","customIframeDomains","iframeFallbackLink","MCPUIConfigContext","createContext","useMCPUIConfig","mergeProps","useContext","MCPUIConfigProvider","props","value","config","_$createComponent","Provider","children"],"mappings":";;;;AA8GO,MAAMA,uBAAoC;AAAA,EAC/CC,sBAAsB;AAAA,EACtBC,4BAA4B,CAAA;AAAA,EAC5BC,cAAc;AAAA,EACdC,qBAAqB,CAAA;AAAA,EACrBC,oBAAoB;AACtB;AAEO,MAAMC,qBAAqBC,QAAAA,cAA2BP,oBAAoB;AAM1E,SAASQ,iBAA8B;AAC5C,SAAOC,mBAAWT,sBAAsBU,QAAAA,WAAWJ,kBAAkB,CAAC;AACxE;AAeO,SAASK,oBAAoBC,OAA8C;AAGhF,QAAMC,QAAQJ,QAAAA,WAAWT,sBAAsB,MAAMY,MAAME,MAAM;AACjE,SAAAC,IAAAA,gBACGT,mBAAmBU,UAAQ;AAAA,IAACH;AAAAA,IAAY,IAAAI,WAAA;AAAA,aACtCL,MAAMK;AAAAA,IAAQ;AAAA,EAAA,CAAA;AAGrB;;;;;"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCPUIConfigContext — host-level rendering policy for the library's iframes.
|
|
3
|
+
*
|
|
4
|
+
* @since v6.21.0
|
|
5
|
+
*
|
|
6
|
+
* ## Why
|
|
7
|
+
*
|
|
8
|
+
* A host that serves `Cross-Origin-Embedder-Policy: credentialless` makes the
|
|
9
|
+
* browser refuse every cross-origin iframe whose own document does not send a
|
|
10
|
+
* COEP header — which is YouTube, Vimeo, Google Docs, Notion and nearly all of
|
|
11
|
+
* `DEFAULT_IFRAME_DOMAINS`. The escape hatch is the boolean HTML attribute
|
|
12
|
+
* `credentialless` on the `<iframe>` itself: the document then loads, but
|
|
13
|
+
* without access to the cookies and storage of its own origin.
|
|
14
|
+
*
|
|
15
|
+
* That trade-off is free for a public video or chart and fatal for an
|
|
16
|
+
* authenticated embed, so the library keys it on the distinction it already
|
|
17
|
+
* makes: `TRUSTED_IFRAME_DOMAINS` (the hosts that receive `allow-same-origin`
|
|
18
|
+
* because they need their own cookies) do NOT get the attribute; everything
|
|
19
|
+
* else does. This context lets a host override that, add its own trusted
|
|
20
|
+
* hosts, and control the "open in a new tab" fallback link.
|
|
21
|
+
*
|
|
22
|
+
* ## Scope — policy only, NOT strings
|
|
23
|
+
*
|
|
24
|
+
* Text lives in `MCPUIStrings` (`MCPUIStringsContext`). This context carries
|
|
25
|
+
* only behavioural switches, and like the strings context every renderer works
|
|
26
|
+
* standalone: with no provider mounted, `DEFAULT_MCPUI_CONFIG` applies.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* import { MCPUIConfigProvider } from '@seed-ship/mcp-ui-solid'
|
|
31
|
+
*
|
|
32
|
+
* <MCPUIConfigProvider config={{ customTrustedIframeDomains: ['embed.acme.com'] }}>
|
|
33
|
+
* <App />
|
|
34
|
+
* </MCPUIConfigProvider>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
import { type JSX } from 'solid-js';
|
|
38
|
+
import type { IframePolicy } from '../types';
|
|
39
|
+
/**
|
|
40
|
+
* Host-level rendering policy. Every field has a default — a provider passes
|
|
41
|
+
* a partial override.
|
|
42
|
+
*/
|
|
43
|
+
export interface MCPUIConfig {
|
|
44
|
+
/**
|
|
45
|
+
* When the library puts the boolean `credentialless` attribute on an
|
|
46
|
+
* `<iframe>` it renders.
|
|
47
|
+
*
|
|
48
|
+
* - `'auto'` (default) — on every iframe whose host is NOT in
|
|
49
|
+
* `TRUSTED_IFRAME_DOMAINS` (plus `customTrustedIframeDomains`). Those
|
|
50
|
+
* hosts already ran without cookies, since their sandbox has no
|
|
51
|
+
* `allow-same-origin`; the attribute is what unblocks them under COEP.
|
|
52
|
+
* - `'always'` — on every iframe, trusted hosts included. An authenticated
|
|
53
|
+
* embed will then render its login screen.
|
|
54
|
+
* - `'never'` — never. The right value for a host that sends no COEP header
|
|
55
|
+
* and does not want its embeds to lose their cookies.
|
|
56
|
+
*
|
|
57
|
+
* Chrome/Edge 110+ honour the attribute; Firefox ignores it (iframes stay
|
|
58
|
+
* blocked while the host sends COEP); Safari ignores the COEP value itself,
|
|
59
|
+
* so nothing is blocked there in the first place.
|
|
60
|
+
*/
|
|
61
|
+
iframeCredentialless: 'auto' | 'always' | 'never';
|
|
62
|
+
/**
|
|
63
|
+
* Extra hosts treated as trusted, on top of `TRUSTED_IFRAME_DOMAINS`:
|
|
64
|
+
* no `credentialless` attribute, and `allow-same-origin` in the sandbox.
|
|
65
|
+
* A subdomain of a listed host matches too.
|
|
66
|
+
*
|
|
67
|
+
* This only RECLASSIFIES a host the allow-list already accepts. To render an
|
|
68
|
+
* iframe whose host is outside `DEFAULT_IFRAME_DOMAINS`, add it to
|
|
69
|
+
* {@link MCPUIConfig.customIframeDomains} with `iframePolicy: 'extend'`.
|
|
70
|
+
*/
|
|
71
|
+
customTrustedIframeDomains: string[];
|
|
72
|
+
/**
|
|
73
|
+
* How `UIResourceRenderer` validates an `iframe` component's host:
|
|
74
|
+
* `'strict'` (default) accepts `DEFAULT_IFRAME_DOMAINS` only, `'extend'`
|
|
75
|
+
* also accepts {@link MCPUIConfig.customIframeDomains}.
|
|
76
|
+
*/
|
|
77
|
+
iframePolicy: IframePolicy;
|
|
78
|
+
/**
|
|
79
|
+
* Extra hosts the allow-list accepts when `iframePolicy` is `'extend'`.
|
|
80
|
+
* Without this, a component pointing at an unlisted host is replaced by the
|
|
81
|
+
* validation card before any renderer runs.
|
|
82
|
+
*/
|
|
83
|
+
customIframeDomains: string[];
|
|
84
|
+
/**
|
|
85
|
+
* When the library renders an "open in a new tab" link under an embed
|
|
86
|
+
* (`strings.iframeOpenInNewTab`).
|
|
87
|
+
*
|
|
88
|
+
* A COEP-blocked iframe fires no event the parent page can observe, so
|
|
89
|
+
* without this the user sees an unexplained blank frame.
|
|
90
|
+
*
|
|
91
|
+
* - `'auto'` (default) — only when the page is cross-origin isolated
|
|
92
|
+
* (`window.crossOriginIsolated`). That flag needs COOP `same-origin` AND
|
|
93
|
+
* COEP, so a host that sends COEP alone still blocks embeds while the
|
|
94
|
+
* flag is false: set `'always'` there. Read after mount, never during
|
|
95
|
+
* render, so SSR markup and hydration agree.
|
|
96
|
+
* - `'always'` / `'never'` — unconditional.
|
|
97
|
+
*/
|
|
98
|
+
iframeFallbackLink: 'auto' | 'always' | 'never';
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Defaults. Chosen so a host that sends no COEP header sees no change from
|
|
102
|
+
* 6.20.0 apart from the fallback link, which `'auto'` keeps hidden there.
|
|
103
|
+
*/
|
|
104
|
+
export declare const DEFAULT_MCPUI_CONFIG: MCPUIConfig;
|
|
105
|
+
export declare const MCPUIConfigContext: import("solid-js").Context<MCPUIConfig>;
|
|
106
|
+
/**
|
|
107
|
+
* Reads the active host config. Returns `DEFAULT_MCPUI_CONFIG` when no
|
|
108
|
+
* `<MCPUIConfigProvider>` is mounted above.
|
|
109
|
+
*/
|
|
110
|
+
export declare function useMCPUIConfig(): MCPUIConfig;
|
|
111
|
+
export interface MCPUIConfigProviderProps {
|
|
112
|
+
/**
|
|
113
|
+
* Partial override of the host config. Any key left unset falls back to
|
|
114
|
+
* `DEFAULT_MCPUI_CONFIG`.
|
|
115
|
+
*/
|
|
116
|
+
config?: Partial<MCPUIConfig>;
|
|
117
|
+
children: JSX.Element;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Provides the host config to every MCP-UI renderer below it.
|
|
121
|
+
* Merges the partial `config` override over the defaults.
|
|
122
|
+
*/
|
|
123
|
+
export declare function MCPUIConfigProvider(props: MCPUIConfigProviderProps): JSX.Element;
|
|
124
|
+
//# sourceMappingURL=MCPUIConfigContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MCPUIConfigContext.d.ts","sourceRoot":"","sources":["../../src/context/MCPUIConfigContext.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAyC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;;;;;;;;OAgBG;IACH,oBAAoB,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;IAEjD;;;;;;;;OAQG;IACH,0BAA0B,EAAE,MAAM,EAAE,CAAA;IAEpC;;;;OAIG;IACH,YAAY,EAAE,YAAY,CAAA;IAE1B;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAE7B;;;;;;;;;;;;;OAaG;IACH,kBAAkB,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;CAChD;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAMlC,CAAA;AAED,eAAO,MAAM,kBAAkB,yCAAmD,CAAA;AAElF;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,CAShF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createComponent } from "solid-js/web";
|
|
2
|
+
import { createContext, mergeProps, useContext } from "solid-js";
|
|
3
|
+
const DEFAULT_MCPUI_CONFIG = {
|
|
4
|
+
iframeCredentialless: "auto",
|
|
5
|
+
customTrustedIframeDomains: [],
|
|
6
|
+
iframePolicy: "strict",
|
|
7
|
+
customIframeDomains: [],
|
|
8
|
+
iframeFallbackLink: "auto"
|
|
9
|
+
};
|
|
10
|
+
const MCPUIConfigContext = createContext(DEFAULT_MCPUI_CONFIG);
|
|
11
|
+
function useMCPUIConfig() {
|
|
12
|
+
return mergeProps(DEFAULT_MCPUI_CONFIG, useContext(MCPUIConfigContext));
|
|
13
|
+
}
|
|
14
|
+
function MCPUIConfigProvider(props) {
|
|
15
|
+
const value = mergeProps(DEFAULT_MCPUI_CONFIG, () => props.config);
|
|
16
|
+
return createComponent(MCPUIConfigContext.Provider, {
|
|
17
|
+
value,
|
|
18
|
+
get children() {
|
|
19
|
+
return props.children;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
DEFAULT_MCPUI_CONFIG,
|
|
25
|
+
MCPUIConfigContext,
|
|
26
|
+
MCPUIConfigProvider,
|
|
27
|
+
useMCPUIConfig
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=MCPUIConfigContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MCPUIConfigContext.js","sources":["../../src/context/MCPUIConfigContext.tsx"],"sourcesContent":["/**\n * MCPUIConfigContext — host-level rendering policy for the library's iframes.\n *\n * @since v6.21.0\n *\n * ## Why\n *\n * A host that serves `Cross-Origin-Embedder-Policy: credentialless` makes the\n * browser refuse every cross-origin iframe whose own document does not send a\n * COEP header — which is YouTube, Vimeo, Google Docs, Notion and nearly all of\n * `DEFAULT_IFRAME_DOMAINS`. The escape hatch is the boolean HTML attribute\n * `credentialless` on the `<iframe>` itself: the document then loads, but\n * without access to the cookies and storage of its own origin.\n *\n * That trade-off is free for a public video or chart and fatal for an\n * authenticated embed, so the library keys it on the distinction it already\n * makes: `TRUSTED_IFRAME_DOMAINS` (the hosts that receive `allow-same-origin`\n * because they need their own cookies) do NOT get the attribute; everything\n * else does. This context lets a host override that, add its own trusted\n * hosts, and control the \"open in a new tab\" fallback link.\n *\n * ## Scope — policy only, NOT strings\n *\n * Text lives in `MCPUIStrings` (`MCPUIStringsContext`). This context carries\n * only behavioural switches, and like the strings context every renderer works\n * standalone: with no provider mounted, `DEFAULT_MCPUI_CONFIG` applies.\n *\n * @example\n * ```tsx\n * import { MCPUIConfigProvider } from '@seed-ship/mcp-ui-solid'\n *\n * <MCPUIConfigProvider config={{ customTrustedIframeDomains: ['embed.acme.com'] }}>\n * <App />\n * </MCPUIConfigProvider>\n * ```\n */\n\nimport { createContext, mergeProps, useContext, type JSX } from 'solid-js'\nimport type { IframePolicy } from '../types'\n\n/**\n * Host-level rendering policy. Every field has a default — a provider passes\n * a partial override.\n */\nexport interface MCPUIConfig {\n /**\n * When the library puts the boolean `credentialless` attribute on an\n * `<iframe>` it renders.\n *\n * - `'auto'` (default) — on every iframe whose host is NOT in\n * `TRUSTED_IFRAME_DOMAINS` (plus `customTrustedIframeDomains`). Those\n * hosts already ran without cookies, since their sandbox has no\n * `allow-same-origin`; the attribute is what unblocks them under COEP.\n * - `'always'` — on every iframe, trusted hosts included. An authenticated\n * embed will then render its login screen.\n * - `'never'` — never. The right value for a host that sends no COEP header\n * and does not want its embeds to lose their cookies.\n *\n * Chrome/Edge 110+ honour the attribute; Firefox ignores it (iframes stay\n * blocked while the host sends COEP); Safari ignores the COEP value itself,\n * so nothing is blocked there in the first place.\n */\n iframeCredentialless: 'auto' | 'always' | 'never'\n\n /**\n * Extra hosts treated as trusted, on top of `TRUSTED_IFRAME_DOMAINS`:\n * no `credentialless` attribute, and `allow-same-origin` in the sandbox.\n * A subdomain of a listed host matches too.\n *\n * This only RECLASSIFIES a host the allow-list already accepts. To render an\n * iframe whose host is outside `DEFAULT_IFRAME_DOMAINS`, add it to\n * {@link MCPUIConfig.customIframeDomains} with `iframePolicy: 'extend'`.\n */\n customTrustedIframeDomains: string[]\n\n /**\n * How `UIResourceRenderer` validates an `iframe` component's host:\n * `'strict'` (default) accepts `DEFAULT_IFRAME_DOMAINS` only, `'extend'`\n * also accepts {@link MCPUIConfig.customIframeDomains}.\n */\n iframePolicy: IframePolicy\n\n /**\n * Extra hosts the allow-list accepts when `iframePolicy` is `'extend'`.\n * Without this, a component pointing at an unlisted host is replaced by the\n * validation card before any renderer runs.\n */\n customIframeDomains: string[]\n\n /**\n * When the library renders an \"open in a new tab\" link under an embed\n * (`strings.iframeOpenInNewTab`).\n *\n * A COEP-blocked iframe fires no event the parent page can observe, so\n * without this the user sees an unexplained blank frame.\n *\n * - `'auto'` (default) — only when the page is cross-origin isolated\n * (`window.crossOriginIsolated`). That flag needs COOP `same-origin` AND\n * COEP, so a host that sends COEP alone still blocks embeds while the\n * flag is false: set `'always'` there. Read after mount, never during\n * render, so SSR markup and hydration agree.\n * - `'always'` / `'never'` — unconditional.\n */\n iframeFallbackLink: 'auto' | 'always' | 'never'\n}\n\n/**\n * Defaults. Chosen so a host that sends no COEP header sees no change from\n * 6.20.0 apart from the fallback link, which `'auto'` keeps hidden there.\n */\nexport const DEFAULT_MCPUI_CONFIG: MCPUIConfig = {\n iframeCredentialless: 'auto',\n customTrustedIframeDomains: [],\n iframePolicy: 'strict',\n customIframeDomains: [],\n iframeFallbackLink: 'auto',\n}\n\nexport const MCPUIConfigContext = createContext<MCPUIConfig>(DEFAULT_MCPUI_CONFIG)\n\n/**\n * Reads the active host config. Returns `DEFAULT_MCPUI_CONFIG` when no\n * `<MCPUIConfigProvider>` is mounted above.\n */\nexport function useMCPUIConfig(): MCPUIConfig {\n return mergeProps(DEFAULT_MCPUI_CONFIG, useContext(MCPUIConfigContext))\n}\n\nexport interface MCPUIConfigProviderProps {\n /**\n * Partial override of the host config. Any key left unset falls back to\n * `DEFAULT_MCPUI_CONFIG`.\n */\n config?: Partial<MCPUIConfig>\n children: JSX.Element\n}\n\n/**\n * Provides the host config to every MCP-UI renderer below it.\n * Merges the partial `config` override over the defaults.\n */\nexport function MCPUIConfigProvider(props: MCPUIConfigProviderProps): JSX.Element {\n // The function source keeps replacement `config` objects reactive while\n // mergeProps fills any omitted key without taking a one-time snapshot.\n const value = mergeProps(DEFAULT_MCPUI_CONFIG, () => props.config)\n return (\n <MCPUIConfigContext.Provider value={value}>\n {props.children}\n </MCPUIConfigContext.Provider>\n )\n}\n"],"names":["DEFAULT_MCPUI_CONFIG","iframeCredentialless","customTrustedIframeDomains","iframePolicy","customIframeDomains","iframeFallbackLink","MCPUIConfigContext","createContext","useMCPUIConfig","mergeProps","useContext","MCPUIConfigProvider","props","value","config","_$createComponent","Provider","children"],"mappings":";;AA8GO,MAAMA,uBAAoC;AAAA,EAC/CC,sBAAsB;AAAA,EACtBC,4BAA4B,CAAA;AAAA,EAC5BC,cAAc;AAAA,EACdC,qBAAqB,CAAA;AAAA,EACrBC,oBAAoB;AACtB;AAEO,MAAMC,qBAAqBC,cAA2BP,oBAAoB;AAM1E,SAASQ,iBAA8B;AAC5C,SAAOC,WAAWT,sBAAsBU,WAAWJ,kBAAkB,CAAC;AACxE;AAeO,SAASK,oBAAoBC,OAA8C;AAGhF,QAAMC,QAAQJ,WAAWT,sBAAsB,MAAMY,MAAME,MAAM;AACjE,SAAAC,gBACGT,mBAAmBU,UAAQ;AAAA,IAACH;AAAAA,IAAY,IAAAI,WAAA;AAAA,aACtCL,MAAMK;AAAAA,IAAQ;AAAA,EAAA,CAAA;AAGrB;"}
|