skybridge 0.0.0-dev.ecfdeac → 0.0.0-dev.ed005a8
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/README.md +10 -16
- package/dist/cli/build-helpers.d.ts +6 -2
- package/dist/cli/build-helpers.js +39 -14
- package/dist/cli/build-helpers.js.map +1 -1
- package/dist/cli/build-helpers.test.js +73 -5
- package/dist/cli/build-helpers.test.js.map +1 -1
- package/dist/cli/build-steps.d.ts +2 -0
- package/dist/cli/build-steps.js +73 -0
- package/dist/cli/build-steps.js.map +1 -0
- package/dist/cli/build-steps.test.js +52 -0
- package/dist/cli/build-steps.test.js.map +1 -0
- package/dist/cli/detect-port.js +0 -1
- package/dist/cli/detect-port.js.map +1 -1
- package/dist/cli/header.d.ts +1 -1
- package/dist/cli/resolve-skybridge-config.d.ts +5 -0
- package/dist/cli/{resolve-views-dir.js → resolve-skybridge-config.js} +4 -3
- package/dist/cli/resolve-skybridge-config.js.map +1 -0
- package/dist/cli/run-plain.d.ts +18 -0
- package/dist/cli/run-plain.js +89 -0
- package/dist/cli/run-plain.js.map +1 -0
- package/dist/cli/use-execute-steps.d.ts +1 -1
- package/dist/cli/use-nodemon.d.ts +14 -0
- package/dist/cli/use-nodemon.js +81 -62
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/cli/use-typescript-check.d.ts +8 -2
- package/dist/cli/use-typescript-check.js +70 -67
- package/dist/cli/use-typescript-check.js.map +1 -1
- package/dist/commands/build.d.ts +0 -2
- package/dist/commands/build.js +2 -61
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts +1 -0
- package/dist/commands/dev.js +35 -3
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.js +2 -2
- package/dist/commands/start.js.map +1 -1
- package/dist/context-warnings.d.ts +5 -0
- package/dist/context-warnings.js +31 -0
- package/dist/context-warnings.js.map +1 -0
- package/dist/context-warnings.test.js +28 -0
- package/dist/context-warnings.test.js.map +1 -0
- package/dist/server/app.d.ts +194 -0
- package/dist/server/app.js +266 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/app.test.js +97 -0
- package/dist/server/app.test.js.map +1 -0
- package/dist/server/auth/discovery.d.ts +2 -1
- package/dist/server/auth/discovery.js +2 -2
- package/dist/server/auth/discovery.js.map +1 -1
- package/dist/server/auth/index.d.ts +35 -5
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/auth/providers/auth0.d.ts +25 -3
- package/dist/server/auth/providers/auth0.js +13 -8
- package/dist/server/auth/providers/auth0.js.map +1 -1
- package/dist/server/auth/providers/auth0.test.js +5 -3
- package/dist/server/auth/providers/auth0.test.js.map +1 -1
- package/dist/server/auth/providers/authplane.d.ts +49 -0
- package/dist/server/auth/providers/authplane.js +57 -0
- package/dist/server/auth/providers/authplane.js.map +1 -0
- package/dist/server/auth/providers/authplane.test.js +143 -0
- package/dist/server/auth/providers/authplane.test.js.map +1 -0
- package/dist/server/auth/providers/clerk.d.ts +40 -3
- package/dist/server/auth/providers/clerk.js +4 -1
- package/dist/server/auth/providers/clerk.js.map +1 -1
- package/dist/server/auth/providers/clerk.test.js +5 -3
- package/dist/server/auth/providers/clerk.test.js.map +1 -1
- package/dist/server/auth/providers/custom.d.ts +20 -4
- package/dist/server/auth/providers/custom.js +33 -11
- package/dist/server/auth/providers/custom.js.map +1 -1
- package/dist/server/auth/providers/custom.test.js +71 -17
- package/dist/server/auth/providers/custom.test.js.map +1 -1
- package/dist/server/auth/providers/descope.d.ts +37 -6
- package/dist/server/auth/providers/descope.js +18 -5
- package/dist/server/auth/providers/descope.js.map +1 -1
- package/dist/server/auth/providers/descope.test.js +42 -17
- package/dist/server/auth/providers/descope.test.js.map +1 -1
- package/dist/server/auth/providers/stytch.d.ts +16 -3
- package/dist/server/auth/providers/stytch.js +4 -1
- package/dist/server/auth/providers/stytch.js.map +1 -1
- package/dist/server/auth/providers/verify-spy.d.ts +12 -0
- package/dist/server/auth/providers/verify-spy.js +21 -0
- package/dist/server/auth/providers/verify-spy.js.map +1 -0
- package/dist/server/auth/providers/workos.d.ts +25 -3
- package/dist/server/auth/providers/workos.js +4 -1
- package/dist/server/auth/providers/workos.js.map +1 -1
- package/dist/server/auth/security-schemes.d.ts +23 -0
- package/dist/server/auth/security-schemes.js +64 -0
- package/dist/server/auth/security-schemes.js.map +1 -0
- package/dist/server/auth/security-schemes.test.d.ts +1 -0
- package/dist/server/auth/security-schemes.test.js +99 -0
- package/dist/server/auth/security-schemes.test.js.map +1 -0
- package/dist/server/auth/setup.d.ts +3 -1
- package/dist/server/auth/setup.js +66 -26
- package/dist/server/auth/setup.js.map +1 -1
- package/dist/server/auth/setup.test.js +349 -20
- package/dist/server/auth/setup.test.js.map +1 -1
- package/dist/server/auth/verify.d.ts +37 -3
- package/dist/server/auth/verify.js +27 -3
- package/dist/server/auth/verify.js.map +1 -1
- package/dist/server/auth/verify.test.js +49 -0
- package/dist/server/auth/verify.test.js.map +1 -1
- package/dist/server/auth-extra.test-d.js +130 -0
- package/dist/server/auth-extra.test-d.js.map +1 -0
- package/dist/server/auth.d.ts +43 -6
- package/dist/server/auth.js +4 -5
- package/dist/server/auth.js.map +1 -1
- package/dist/server/build-manifest.test.js +7 -6
- package/dist/server/build-manifest.test.js.map +1 -1
- package/dist/server/content-helpers.d.ts +1 -1
- package/dist/server/content-helpers.js.map +1 -1
- package/dist/server/express.d.ts +23 -3
- package/dist/server/express.js +38 -32
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +220 -103
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/file-ref.d.ts +1 -1
- package/dist/server/file-ref.js +1 -1
- package/dist/server/file-ref.js.map +1 -1
- package/dist/server/host.d.ts +2 -0
- package/dist/server/host.js +11 -0
- package/dist/server/host.js.map +1 -0
- package/dist/server/host.test.d.ts +1 -0
- package/dist/server/host.test.js +13 -0
- package/dist/server/host.test.js.map +1 -0
- package/dist/server/index.d.ts +16 -9
- package/dist/server/index.js +9 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp-errors.test.d.ts +1 -0
- package/dist/server/mcp-errors.test.js +41 -0
- package/dist/server/mcp-errors.test.js.map +1 -0
- package/dist/server/middleware.d.ts +35 -10
- package/dist/server/middleware.js +33 -0
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/middleware.test-d.js +1 -1
- package/dist/server/middleware.test-d.js.map +1 -1
- package/dist/server/middleware.test.js +242 -134
- package/dist/server/middleware.test.js.map +1 -1
- package/dist/server/register-tool.test.d.ts +1 -0
- package/dist/server/register-tool.test.js +27 -0
- package/dist/server/register-tool.test.js.map +1 -0
- package/dist/server/server.d.ts +133 -116
- package/dist/server/server.js +251 -346
- package/dist/server/server.js.map +1 -1
- package/dist/server/skills-integration.test.d.ts +1 -0
- package/dist/server/skills-integration.test.js +86 -0
- package/dist/server/skills-integration.test.js.map +1 -0
- package/dist/server/skills.d.ts +27 -0
- package/dist/server/skills.js +188 -0
- package/dist/server/skills.js.map +1 -0
- package/dist/server/skills.test.d.ts +1 -0
- package/dist/server/skills.test.js +243 -0
- package/dist/server/skills.test.js.map +1 -0
- package/dist/server/templateHelper.d.ts +0 -3
- package/dist/server/templateHelper.js.map +1 -1
- package/dist/server/templates.generated.js +4 -8
- package/dist/server/templates.generated.js.map +1 -1
- package/dist/server/tool-extra.test.d.ts +1 -0
- package/dist/server/tool-extra.test.js +88 -0
- package/dist/server/tool-extra.test.js.map +1 -0
- package/dist/server/view-name.test-d.d.ts +1 -0
- package/dist/server/view-name.test-d.js +8 -0
- package/dist/server/view-name.test-d.js.map +1 -0
- package/dist/server/view-resource-resolution.test.js +105 -17
- package/dist/server/view-resource-resolution.test.js.map +1 -1
- package/dist/server/viewsDevServer.js +4 -1
- package/dist/server/viewsDevServer.js.map +1 -1
- package/dist/test/utils.d.ts +9 -11
- package/dist/test/utils.js +220 -201
- package/dist/test/utils.js.map +1 -1
- package/dist/test/view.test.js +105 -133
- package/dist/test/view.test.js.map +1 -1
- package/dist/views/index.d.ts +10 -0
- package/dist/views/index.js +3 -0
- package/dist/views/index.js.map +1 -0
- package/dist/{web/plugin → views}/scan-views.js +1 -1
- package/dist/views/scan-views.js.map +1 -0
- package/dist/views/scan-views.test.d.ts +1 -0
- package/dist/views/scan-views.test.js.map +1 -0
- package/dist/views/validate-view.d.ts +1 -0
- package/dist/{web/plugin → views}/validate-view.js +2 -2
- package/dist/views/validate-view.js.map +1 -0
- package/dist/views/validate-view.test.d.ts +1 -0
- package/dist/views/validate-view.test.js.map +1 -0
- package/dist/web/bridges/adaptor.d.ts +51 -0
- package/dist/web/bridges/adaptor.js +327 -0
- package/dist/web/bridges/adaptor.js.map +1 -0
- package/dist/web/bridges/adaptor.test.d.ts +1 -0
- package/dist/web/bridges/adaptor.test.js +225 -0
- package/dist/web/bridges/adaptor.test.js.map +1 -0
- package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -2
- package/dist/web/bridges/apps-sdk/bridge.js +15 -4
- package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
- package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
- package/dist/web/bridges/apps-sdk/index.js +0 -1
- package/dist/web/bridges/apps-sdk/index.js.map +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
- package/dist/web/bridges/get-adaptor.d.ts +4 -4
- package/dist/web/bridges/get-adaptor.js +6 -11
- package/dist/web/bridges/get-adaptor.js.map +1 -1
- package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
- package/dist/web/bridges/get-adaptor.test.js +32 -0
- package/dist/web/bridges/get-adaptor.test.js.map +1 -0
- package/dist/web/bridges/mcp-app/bridge.d.ts +13 -2
- package/dist/web/bridges/mcp-app/bridge.js +52 -8
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
- package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
- package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
- package/dist/web/bridges/mcp-app/index.d.ts +0 -1
- package/dist/web/bridges/mcp-app/index.js +0 -1
- package/dist/web/bridges/mcp-app/index.js.map +1 -1
- package/dist/web/bridges/mcp-app/types.d.ts +2 -0
- package/dist/web/bridges/mcp-app/types.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
- package/dist/web/bridges/mcp-app/view-tools.test.js +6 -7
- package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -1
- package/dist/web/bridges/types.d.ts +27 -12
- package/dist/web/bridges/types.js +14 -1
- package/dist/web/bridges/types.js.map +1 -1
- package/dist/web/bridges/types.test.d.ts +1 -0
- package/dist/web/bridges/types.test.js +19 -0
- package/dist/web/bridges/types.test.js.map +1 -0
- package/dist/web/components/modal-provider.d.ts +1 -1
- package/dist/web/components/modal-provider.js +4 -3
- package/dist/web/components/modal-provider.js.map +1 -1
- package/dist/web/create-store.test.js +10 -7
- package/dist/web/create-store.test.js.map +1 -1
- package/dist/web/data-llm.d.ts +1 -1
- package/dist/web/data-llm.test.js +20 -7
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/generate-helpers.d.ts +22 -18
- package/dist/web/generate-helpers.js +19 -15
- package/dist/web/generate-helpers.js.map +1 -1
- package/dist/web/generate-helpers.test-d.js +3 -3
- package/dist/web/generate-helpers.test-d.js.map +1 -1
- package/dist/web/generate-helpers.test.js +2 -2
- package/dist/web/generate-helpers.test.js.map +1 -1
- package/dist/web/hooks/index.d.ts +2 -1
- package/dist/web/hooks/index.js +2 -1
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/test/utils.d.ts +2 -1
- package/dist/web/hooks/test/utils.js +1 -1
- package/dist/web/hooks/test/utils.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test.js +39 -25
- package/dist/web/hooks/use-call-tool.test.js.map +1 -1
- package/dist/web/hooks/use-display-mode.d.ts +1 -1
- package/dist/web/hooks/use-display-mode.js +1 -1
- package/dist/web/hooks/use-display-mode.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test.js +57 -21
- package/dist/web/hooks/use-display-mode.test.js.map +1 -1
- package/dist/web/hooks/use-download.d.ts +1 -3
- package/dist/web/hooks/use-download.js +1 -2
- package/dist/web/hooks/use-download.js.map +1 -1
- package/dist/web/hooks/use-download.test.js +18 -10
- package/dist/web/hooks/use-download.test.js.map +1 -1
- package/dist/web/hooks/use-files.test.js +11 -3
- package/dist/web/hooks/use-files.test.js.map +1 -1
- package/dist/web/hooks/use-host.d.ts +22 -0
- package/dist/web/hooks/use-host.js +30 -0
- package/dist/web/hooks/use-host.js.map +1 -0
- package/dist/web/hooks/use-host.test.d.ts +1 -0
- package/dist/web/hooks/use-host.test.js +59 -0
- package/dist/web/hooks/use-host.test.js.map +1 -0
- package/dist/web/hooks/use-open-external.test.js +15 -5
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-register-view-tool.d.ts +2 -3
- package/dist/web/hooks/use-register-view-tool.js.map +1 -1
- package/dist/web/hooks/use-request-close.test.js +35 -40
- package/dist/web/hooks/use-request-close.test.js.map +1 -1
- package/dist/web/hooks/use-request-modal.test.js +11 -1
- package/dist/web/hooks/use-request-modal.test.js.map +1 -1
- package/dist/web/hooks/use-request-size.d.ts +1 -1
- package/dist/web/hooks/use-request-size.js +1 -1
- package/dist/web/hooks/use-request-size.js.map +1 -1
- package/dist/web/hooks/use-request-size.test.js +35 -53
- package/dist/web/hooks/use-request-size.test.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
- package/dist/web/hooks/use-tool-info.d.ts +1 -20
- package/dist/web/hooks/use-tool-info.js +0 -1
- package/dist/web/hooks/use-tool-info.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test-d.js +0 -5
- package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js +38 -33
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.d.ts +3 -2
- package/dist/web/hooks/use-user.js +4 -3
- package/dist/web/hooks/use-user.js.map +1 -1
- package/dist/web/hooks/use-user.test.js +85 -37
- package/dist/web/hooks/use-user.test.js.map +1 -1
- package/dist/web/hooks/use-view-state.js +19 -9
- package/dist/web/hooks/use-view-state.js.map +1 -1
- package/dist/web/hooks/use-view-state.test.js +39 -4
- package/dist/web/hooks/use-view-state.test.js.map +1 -1
- package/dist/web/hooks/use-viewport.d.ts +20 -0
- package/dist/web/hooks/use-viewport.js +21 -0
- package/dist/web/hooks/use-viewport.js.map +1 -0
- package/dist/web/hooks/use-viewport.test.d.ts +1 -0
- package/dist/web/hooks/use-viewport.test.js +109 -0
- package/dist/web/hooks/use-viewport.test.js.map +1 -0
- package/dist/web/mount-view.d.ts +3 -2
- package/dist/web/mount-view.js +5 -8
- package/dist/web/mount-view.js.map +1 -1
- package/package.json +31 -28
- package/dist/cli/resolve-views-dir.d.ts +0 -1
- package/dist/cli/resolve-views-dir.js.map +0 -1
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -29
- package/dist/web/bridges/apps-sdk/adaptor.js +0 -117
- package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -53
- package/dist/web/bridges/mcp-app/adaptor.js +0 -283
- package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
- package/dist/web/hooks/use-layout.d.ts +0 -24
- package/dist/web/hooks/use-layout.js +0 -25
- package/dist/web/hooks/use-layout.js.map +0 -1
- package/dist/web/hooks/use-layout.test.js +0 -96
- package/dist/web/hooks/use-layout.test.js.map +0 -1
- package/dist/web/plugin/data-llm.test.js +0 -81
- package/dist/web/plugin/data-llm.test.js.map +0 -1
- package/dist/web/plugin/plugin.d.ts +0 -33
- package/dist/web/plugin/plugin.js +0 -189
- package/dist/web/plugin/plugin.js.map +0 -1
- package/dist/web/plugin/scan-views.js.map +0 -1
- package/dist/web/plugin/scan-views.test.js.map +0 -1
- package/dist/web/plugin/transform-data-llm.d.ts +0 -12
- package/dist/web/plugin/transform-data-llm.js +0 -96
- package/dist/web/plugin/transform-data-llm.js.map +0 -1
- package/dist/web/plugin/transform-data-llm.test.js +0 -81
- package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
- package/dist/web/plugin/validate-view.d.ts +0 -1
- package/dist/web/plugin/validate-view.js.map +0 -1
- package/dist/web/plugin/validate-view.test.js.map +0 -1
- /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-steps.test.d.ts} +0 -0
- /package/dist/{web/plugin/data-llm.test.d.ts → context-warnings.test.d.ts} +0 -0
- /package/dist/{web/plugin/scan-views.test.d.ts → server/app.test.d.ts} +0 -0
- /package/dist/{web/plugin/validate-view.test.d.ts → server/auth/providers/authplane.test.d.ts} +0 -0
- /package/dist/{web/plugin/transform-data-llm.test.d.ts → server/auth-extra.test-d.d.ts} +0 -0
- /package/dist/{web/plugin → views}/scan-views.d.ts +0 -0
- /package/dist/{web/plugin → views}/scan-views.test.js +0 -0
- /package/dist/{web/plugin → views}/validate-view.test.js +0 -0
package/dist/test/view.test.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import { Client } from "@modelcontextprotocol/
|
|
3
|
-
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
2
|
+
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
|
|
4
3
|
import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
|
|
5
|
-
import {
|
|
4
|
+
import { TOOL_OUTPUT_WARNING_TOKENS } from "../context-warnings.js";
|
|
5
|
+
import { Skybridge } from "../server/app.js";
|
|
6
6
|
import { createMockExtra, createMockMcpServer, resetTestEnv, setTestEnv, } from "./utils.js";
|
|
7
7
|
const mockManifest = {
|
|
8
8
|
"skybridge:view:my-view": {
|
|
@@ -74,20 +74,24 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
74
74
|
const serverUrl = `http://${host}`;
|
|
75
75
|
const hmrUrl = `ws://${host}`;
|
|
76
76
|
const mockExtra = createMockExtra(host);
|
|
77
|
-
const result = await appsSdkResourceCallback(new URL("ui://views/apps
|
|
77
|
+
const result = await appsSdkResourceCallback(new URL("ui://views/ext-apps/my-view.html"), mockExtra);
|
|
78
78
|
expect(mockRegisterTool).toHaveBeenCalled();
|
|
79
79
|
expect(result).toEqual({
|
|
80
80
|
contents: [
|
|
81
81
|
{
|
|
82
|
-
uri: "ui://views/apps
|
|
83
|
-
mimeType: "text/html
|
|
82
|
+
uri: "ui://views/ext-apps/my-view.html",
|
|
83
|
+
mimeType: "text/html;profile=mcp-app",
|
|
84
84
|
text: expect.stringContaining('<div id="root"></div>'),
|
|
85
85
|
_meta: {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
ui: {
|
|
87
|
+
csp: {
|
|
88
|
+
resourceDomains: [serverUrl],
|
|
89
|
+
connectDomains: [serverUrl, hmrUrl],
|
|
90
|
+
baseUriDomains: [serverUrl],
|
|
91
|
+
},
|
|
92
|
+
domain: serverUrl,
|
|
93
|
+
description: "Test view",
|
|
89
94
|
},
|
|
90
|
-
"openai/widgetDomain": serverUrl,
|
|
91
95
|
"openai/widgetDescription": "Test view",
|
|
92
96
|
},
|
|
93
97
|
},
|
|
@@ -113,20 +117,24 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
113
117
|
const host = "myapp.com";
|
|
114
118
|
const serverUrl = `https://${host}`;
|
|
115
119
|
const mockExtra = createMockExtra(host);
|
|
116
|
-
const versionedUri = `ui://views/apps
|
|
120
|
+
const versionedUri = `ui://views/ext-apps/my-view.html${expectedVersionParam("assets/my-view-abc123.js", "style.css")}`;
|
|
117
121
|
const result = await appsSdkResourceCallback(new URL(versionedUri), mockExtra);
|
|
118
122
|
expect(result).toEqual({
|
|
119
123
|
contents: [
|
|
120
124
|
{
|
|
121
125
|
uri: versionedUri,
|
|
122
|
-
mimeType: "text/html
|
|
126
|
+
mimeType: "text/html;profile=mcp-app",
|
|
123
127
|
text: expect.stringContaining('<div id="root"></div>'),
|
|
124
128
|
_meta: {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
129
|
+
ui: {
|
|
130
|
+
csp: {
|
|
131
|
+
resourceDomains: [serverUrl],
|
|
132
|
+
connectDomains: [serverUrl],
|
|
133
|
+
baseUriDomains: [serverUrl],
|
|
134
|
+
},
|
|
135
|
+
domain: serverUrl,
|
|
136
|
+
description: "Test view",
|
|
128
137
|
},
|
|
129
|
-
"openai/widgetDomain": serverUrl,
|
|
130
138
|
"openai/widgetDescription": "Test view",
|
|
131
139
|
},
|
|
132
140
|
},
|
|
@@ -145,7 +153,7 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
145
153
|
view: { component: "my-view", description: "Test view" },
|
|
146
154
|
}, vi.fn());
|
|
147
155
|
const extAppsResourceCallback = mockRegisterResource.mock
|
|
148
|
-
.calls[
|
|
156
|
+
.calls[0]?.[3];
|
|
149
157
|
expect(extAppsResourceCallback).toBeDefined();
|
|
150
158
|
const forwardedUrl = "https://everything-3a2c1264.staging.alpic.live/mcp?foo=bar";
|
|
151
159
|
const expectedDomain = `${crypto
|
|
@@ -170,9 +178,10 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
170
178
|
description: "Test view",
|
|
171
179
|
domain: expectedDomain,
|
|
172
180
|
},
|
|
181
|
+
"openai/widgetDescription": "Test view",
|
|
173
182
|
});
|
|
174
183
|
});
|
|
175
|
-
it("should register
|
|
184
|
+
it("should register a single ext-apps resource", async () => {
|
|
176
185
|
server.registerTool({
|
|
177
186
|
name: "my-view",
|
|
178
187
|
description: "Test tool",
|
|
@@ -182,37 +191,14 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
182
191
|
prefersBorder: true,
|
|
183
192
|
},
|
|
184
193
|
}, vi.fn());
|
|
185
|
-
expect(mockRegisterResource).toHaveBeenCalledTimes(
|
|
186
|
-
const
|
|
194
|
+
expect(mockRegisterResource).toHaveBeenCalledTimes(1);
|
|
195
|
+
const resourceCallback = mockRegisterResource.mock
|
|
187
196
|
.calls[0]?.[3];
|
|
188
197
|
const host = "localhost:3000";
|
|
189
198
|
const serverUrl = `http://${host}`;
|
|
190
199
|
const hmrUrl = `ws://${host}`;
|
|
191
|
-
const
|
|
192
|
-
expect(
|
|
193
|
-
contents: [
|
|
194
|
-
{
|
|
195
|
-
uri: "ui://views/apps-sdk/my-view.html",
|
|
196
|
-
mimeType: "text/html+skybridge",
|
|
197
|
-
text: expect.stringContaining('<div id="root"></div>'),
|
|
198
|
-
_meta: {
|
|
199
|
-
"openai/widgetCSP": {
|
|
200
|
-
resource_domains: [serverUrl],
|
|
201
|
-
connect_domains: [serverUrl, hmrUrl],
|
|
202
|
-
},
|
|
203
|
-
"openai/widgetDomain": serverUrl,
|
|
204
|
-
"openai/widgetDescription": "Test view",
|
|
205
|
-
"openai/widgetPrefersBorder": true,
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
});
|
|
210
|
-
expect(appsSdkResult.contents[0]?.text).toContain('window.skybridge = { hostType: "apps-sdk", serverUrl: "http://localhost:3000" };');
|
|
211
|
-
const extAppsResourceCallback = mockRegisterResource.mock
|
|
212
|
-
.calls[1]?.[3];
|
|
213
|
-
expect(extAppsResourceCallback).toBeDefined();
|
|
214
|
-
const extAppsResult = await extAppsResourceCallback(new URL("ui://views/ext-apps/my-view.html"), createMockExtra(host));
|
|
215
|
-
expect(extAppsResult).toEqual({
|
|
200
|
+
const result = await resourceCallback(new URL("ui://views/ext-apps/my-view.html"), createMockExtra(host));
|
|
201
|
+
expect(result).toEqual({
|
|
216
202
|
contents: [
|
|
217
203
|
{
|
|
218
204
|
uri: "ui://views/ext-apps/my-view.html",
|
|
@@ -229,41 +215,24 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
229
215
|
description: "Test view",
|
|
230
216
|
prefersBorder: true,
|
|
231
217
|
},
|
|
218
|
+
"openai/widgetDescription": "Test view",
|
|
232
219
|
},
|
|
233
220
|
},
|
|
234
221
|
],
|
|
235
222
|
});
|
|
236
|
-
expect(
|
|
223
|
+
expect(result.contents[0]?.text).toContain('window.skybridge = { serverUrl: "http://localhost:3000" };');
|
|
237
224
|
});
|
|
238
|
-
it("should
|
|
225
|
+
it("should advertise the single resource via ui.resourceUri only (no openai/outputTemplate)", async () => {
|
|
239
226
|
server.registerTool({
|
|
240
227
|
name: "my-view",
|
|
241
228
|
description: "Test tool",
|
|
242
229
|
view: { component: "my-view", description: "Test view" },
|
|
243
230
|
}, vi.fn());
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
expect(toolConfig._meta
|
|
248
|
-
expect(toolConfig._meta?.
|
|
249
|
-
resourceUri: "ui://views/ext-apps/my-view.html",
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
it("should register tool with openai/outputTemplate when apps-sdk only", async () => {
|
|
253
|
-
server.registerTool({
|
|
254
|
-
name: "my-view",
|
|
255
|
-
description: "Test tool",
|
|
256
|
-
view: {
|
|
257
|
-
component: "my-view",
|
|
258
|
-
description: "Test view",
|
|
259
|
-
hosts: ["apps-sdk"],
|
|
260
|
-
},
|
|
261
|
-
}, vi.fn());
|
|
262
|
-
expect(mockRegisterTool).toHaveBeenCalledTimes(1);
|
|
263
|
-
const toolCallArgs = mockRegisterTool.mock.calls[0];
|
|
264
|
-
const toolConfig = toolCallArgs?.[1];
|
|
265
|
-
expect(toolConfig._meta).not.toHaveProperty("ui");
|
|
266
|
-
expect(toolConfig._meta?.["openai/outputTemplate"]).toBe("ui://views/apps-sdk/my-view.html");
|
|
231
|
+
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
232
|
+
const uri = "ui://views/ext-apps/my-view.html";
|
|
233
|
+
expect(toolConfig._meta?.ui?.resourceUri).toBe(uri);
|
|
234
|
+
expect(toolConfig._meta?.["ui/resourceUri"]).toBe(uri);
|
|
235
|
+
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
267
236
|
});
|
|
268
237
|
it("should not version view URIs in development", () => {
|
|
269
238
|
server.registerTool({
|
|
@@ -272,12 +241,11 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
272
241
|
view: { component: "my-view", description: "Test view" },
|
|
273
242
|
}, vi.fn());
|
|
274
243
|
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
275
|
-
expect(toolConfig._meta?.["openai/outputTemplate"]).
|
|
244
|
+
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
276
245
|
expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/my-view.html");
|
|
277
|
-
// The URI registered with the resource handler must match
|
|
278
|
-
//
|
|
279
|
-
expect(mockRegisterResource.mock.calls[0]?.[1]).toBe("ui://views/apps
|
|
280
|
-
expect(mockRegisterResource.mock.calls[1]?.[1]).toBe("ui://views/ext-apps/my-view.html");
|
|
246
|
+
// The URI registered with the resource handler must match ui.resourceUri
|
|
247
|
+
// exactly so the SDK can resolve `resources/read` requests.
|
|
248
|
+
expect(mockRegisterResource.mock.calls[0]?.[1]).toBe("ui://views/ext-apps/my-view.html");
|
|
281
249
|
});
|
|
282
250
|
it("should append a stable content hash to view URIs in production", () => {
|
|
283
251
|
setTestEnv({ NODE_ENV: "production" });
|
|
@@ -288,10 +256,9 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
288
256
|
}, vi.fn());
|
|
289
257
|
const expected = expectedVersionParam("assets/my-view-abc123.js", "style.css");
|
|
290
258
|
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
291
|
-
expect(toolConfig._meta?.["openai/outputTemplate"]).
|
|
259
|
+
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
292
260
|
expect(toolConfig._meta?.ui?.resourceUri).toBe(`ui://views/ext-apps/my-view.html${expected}`);
|
|
293
|
-
expect(mockRegisterResource.mock.calls[0]?.[1]).toBe(`ui://views/apps
|
|
294
|
-
expect(mockRegisterResource.mock.calls[1]?.[1]).toBe(`ui://views/ext-apps/my-view.html${expected}`);
|
|
261
|
+
expect(mockRegisterResource.mock.calls[0]?.[1]).toBe(`ui://views/ext-apps/my-view.html${expected}`);
|
|
295
262
|
});
|
|
296
263
|
it("should produce different version params for views with different bundles", () => {
|
|
297
264
|
setTestEnv({ NODE_ENV: "production" });
|
|
@@ -305,8 +272,8 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
305
272
|
description: "Second tool",
|
|
306
273
|
view: { component: "folder-view" },
|
|
307
274
|
}, vi.fn());
|
|
308
|
-
const myviewTemplate =
|
|
309
|
-
const folderviewTemplate =
|
|
275
|
+
const myviewTemplate = mockRegisterTool.mock.calls[0][1]._meta?.ui?.resourceUri;
|
|
276
|
+
const folderviewTemplate = mockRegisterTool.mock.calls[1][1]._meta?.ui?.resourceUri;
|
|
310
277
|
expect(myviewTemplate).not.toEqual(folderviewTemplate);
|
|
311
278
|
expect(myviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
|
|
312
279
|
expect(folderviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
|
|
@@ -319,26 +286,7 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
319
286
|
view: { component: "unknown-view" },
|
|
320
287
|
}, vi.fn());
|
|
321
288
|
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
322
|
-
expect(toolConfig._meta?.
|
|
323
|
-
});
|
|
324
|
-
it("should register tool with ui.resourceUri only when mcp-app only", async () => {
|
|
325
|
-
server.registerTool({
|
|
326
|
-
name: "my-view",
|
|
327
|
-
description: "Test tool",
|
|
328
|
-
view: {
|
|
329
|
-
component: "my-view",
|
|
330
|
-
description: "Test view",
|
|
331
|
-
hosts: ["mcp-app"],
|
|
332
|
-
},
|
|
333
|
-
}, vi.fn());
|
|
334
|
-
expect(mockRegisterTool).toHaveBeenCalledTimes(1);
|
|
335
|
-
const toolCallArgs = mockRegisterTool.mock.calls[0];
|
|
336
|
-
const toolConfig = toolCallArgs?.[1];
|
|
337
|
-
expect(toolConfig._meta).toHaveProperty("ui");
|
|
338
|
-
expect(toolConfig._meta?.ui).toEqual({
|
|
339
|
-
resourceUri: "ui://views/ext-apps/my-view.html",
|
|
340
|
-
});
|
|
341
|
-
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
289
|
+
expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/unknown-view.html");
|
|
342
290
|
});
|
|
343
291
|
it("should inject viewUUID into _meta of tool callback results", async () => {
|
|
344
292
|
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
@@ -358,6 +306,21 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
358
306
|
expect(typeof result._meta?.viewUUID).toBe("string");
|
|
359
307
|
expect(result._meta?.viewUUID).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
|
|
360
308
|
});
|
|
309
|
+
it("warns when a tool callback returns large model-visible output", async () => {
|
|
310
|
+
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
311
|
+
server.registerTool({ name: "large-output", description: "Test tool" }, vi.fn().mockResolvedValue({
|
|
312
|
+
content: [
|
|
313
|
+
{
|
|
314
|
+
type: "text",
|
|
315
|
+
text: "x".repeat(TOOL_OUTPUT_WARNING_TOKENS * 4),
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
}));
|
|
319
|
+
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
320
|
+
await wrappedCallback({}, {});
|
|
321
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Tool "large-output" returned'));
|
|
322
|
+
warnSpy.mockRestore();
|
|
323
|
+
});
|
|
361
324
|
it("should preserve existing _meta when injecting viewUUID", async () => {
|
|
362
325
|
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
363
326
|
content: [{ type: "text", text: "result" }],
|
|
@@ -476,11 +439,12 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
476
439
|
const host = "localhost:3000";
|
|
477
440
|
const serverUrl = `http://${host}`;
|
|
478
441
|
const hmrUrl = `ws://${host}`;
|
|
479
|
-
const result = await appsSdkCallback(new URL("ui://views/apps
|
|
442
|
+
const result = await appsSdkCallback(new URL("ui://views/ext-apps/csp-tool.html"), createMockExtra(host));
|
|
480
443
|
const meta = result.contents[0]?._meta;
|
|
481
|
-
expect(meta
|
|
482
|
-
|
|
483
|
-
|
|
444
|
+
expect(meta.ui?.csp).toEqual({
|
|
445
|
+
resourceDomains: [serverUrl, "https://cdn.example.com"],
|
|
446
|
+
connectDomains: [serverUrl, hmrUrl, "https://api.example.com"],
|
|
447
|
+
baseUriDomains: [serverUrl],
|
|
484
448
|
});
|
|
485
449
|
});
|
|
486
450
|
it("should let view._meta override framework-computed keys", async () => {
|
|
@@ -492,18 +456,20 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
492
456
|
description: "Test view",
|
|
493
457
|
csp: { connectDomains: ["https://api.x.com"] },
|
|
494
458
|
_meta: {
|
|
495
|
-
|
|
496
|
-
|
|
459
|
+
ui: {
|
|
460
|
+
csp: {
|
|
461
|
+
connectDomains: ["https://api.y.com"],
|
|
462
|
+
},
|
|
497
463
|
},
|
|
498
464
|
},
|
|
499
465
|
},
|
|
500
466
|
}, vi.fn());
|
|
501
467
|
const appsSdkCallback = mockRegisterResource.mock
|
|
502
468
|
.calls[0]?.[3];
|
|
503
|
-
const result = await appsSdkCallback(new URL("ui://views/apps
|
|
469
|
+
const result = await appsSdkCallback(new URL("ui://views/ext-apps/override-tool.html"), createMockExtra("localhost:3000"));
|
|
504
470
|
const meta = result.contents[0]?._meta;
|
|
505
|
-
expect(meta
|
|
506
|
-
|
|
471
|
+
expect(meta.ui?.csp).toEqual({
|
|
472
|
+
connectDomains: ["https://api.y.com"],
|
|
507
473
|
});
|
|
508
474
|
});
|
|
509
475
|
it("should pass user _meta keys through to tool config", () => {
|
|
@@ -527,42 +493,48 @@ describe("resources/list view _meta injection", () => {
|
|
|
527
493
|
afterEach(() => resetTestEnv());
|
|
528
494
|
it("attaches CSP, domain, and connectDomains _meta to view resources at list time", async () => {
|
|
529
495
|
setTestEnv({ NODE_ENV: "production" });
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
496
|
+
const app = new Skybridge({
|
|
497
|
+
name: "test",
|
|
498
|
+
version: "1.0.0",
|
|
499
|
+
handler: (server) => server.registerTool({
|
|
500
|
+
name: "start",
|
|
501
|
+
description: "Start",
|
|
502
|
+
view: {
|
|
503
|
+
component: "my-view",
|
|
504
|
+
description: "Onboarding deck",
|
|
505
|
+
domain: "skybridge.tech",
|
|
506
|
+
csp: {
|
|
507
|
+
resourceDomains: ["https://fonts.googleapis.com"],
|
|
508
|
+
redirectDomains: ["https://docs.skybridge.tech"],
|
|
509
|
+
},
|
|
541
510
|
},
|
|
542
|
-
},
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
})
|
|
511
|
+
}, vi.fn().mockResolvedValue({
|
|
512
|
+
content: [{ type: "text", text: "ok" }],
|
|
513
|
+
structuredContent: {},
|
|
514
|
+
})),
|
|
515
|
+
});
|
|
516
|
+
const instance = await app.createServerInstance();
|
|
547
517
|
const client = new Client({ name: "test-client", version: "1.0.0" });
|
|
548
518
|
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
549
|
-
await
|
|
519
|
+
await instance.connect(serverTransport);
|
|
550
520
|
await client.connect(clientTransport);
|
|
551
521
|
const { resources } = await client.listResources();
|
|
552
522
|
await client.close();
|
|
553
|
-
await
|
|
523
|
+
await instance.close();
|
|
554
524
|
const appsSdk = resources.find((r) => r.uri.includes("apps-sdk"));
|
|
555
525
|
const extApps = resources.find((r) => r.uri.includes("ext-apps"));
|
|
556
|
-
expect(appsSdk
|
|
526
|
+
expect(appsSdk).toBeUndefined();
|
|
557
527
|
expect(extApps?._meta).toBeDefined();
|
|
558
|
-
const
|
|
559
|
-
expect(appsSdkCsp.connect_domains?.length).toBeGreaterThan(0);
|
|
560
|
-
expect(appsSdkCsp.resource_domains).toContain("https://fonts.googleapis.com");
|
|
561
|
-
expect(appsSdk?._meta?.["openai/widgetDomain"]).toBe("skybridge.tech");
|
|
562
|
-
const extUi = (extApps?._meta).ui;
|
|
528
|
+
const extUi = extApps._meta?.ui;
|
|
563
529
|
expect(extUi?.csp?.connectDomains?.length).toBeGreaterThan(0);
|
|
564
530
|
expect(extUi?.csp?.resourceDomains).toContain("https://fonts.googleapis.com");
|
|
565
531
|
expect(extUi?.domain).toBe("skybridge.tech");
|
|
532
|
+
const meta = extApps?._meta;
|
|
533
|
+
expect(meta["openai/widgetDescription"]).toBe("Onboarding deck");
|
|
534
|
+
expect(meta["openai/widgetCSP"]?.redirect_domains).toEqual([
|
|
535
|
+
"https://docs.skybridge.tech",
|
|
536
|
+
]);
|
|
537
|
+
expect(meta.ui?.csp).not.toHaveProperty("redirectDomains");
|
|
566
538
|
});
|
|
567
539
|
});
|
|
568
540
|
//# sourceMappingURL=view.test.js.map
|