skybridge 0.0.0-dev.f7e85aa → 0.0.0-dev.f80c2df
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 +124 -124
- package/dist/cli/build-helpers.d.ts +11 -0
- package/dist/cli/build-helpers.js +102 -0
- package/dist/cli/build-helpers.js.map +1 -0
- package/dist/cli/build-helpers.test.js +119 -0
- package/dist/cli/build-helpers.test.js.map +1 -0
- 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.d.ts +2 -2
- package/dist/cli/detect-port.js +9 -20
- package/dist/cli/detect-port.js.map +1 -1
- package/dist/cli/header.d.ts +1 -1
- package/dist/cli/header.js.map +1 -1
- package/dist/cli/resolve-views-dir.d.ts +1 -0
- package/dist/cli/resolve-views-dir.js +17 -0
- package/dist/cli/resolve-views-dir.js.map +1 -0
- package/dist/cli/run-command.js.map +1 -1
- 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/telemetry.js.map +1 -1
- package/dist/cli/tunnel-control-server.d.ts +9 -0
- package/dist/cli/tunnel-control-server.js +31 -0
- package/dist/cli/tunnel-control-server.js.map +1 -0
- package/dist/cli/tunnel-control-server.test.js +39 -0
- package/dist/cli/tunnel-control-server.test.js.map +1 -0
- package/dist/cli/tunnel-handler.d.ts +3 -0
- package/dist/cli/tunnel-handler.js +48 -0
- package/dist/cli/tunnel-handler.js.map +1 -0
- package/dist/cli/tunnel-handler.test.js +105 -0
- package/dist/cli/tunnel-handler.test.js.map +1 -0
- package/dist/cli/tunnel.d.ts +57 -0
- package/dist/cli/tunnel.js +154 -0
- package/dist/cli/tunnel.js.map +1 -0
- package/dist/cli/tunnel.test.d.ts +1 -0
- package/dist/cli/tunnel.test.js +190 -0
- package/dist/cli/tunnel.test.js.map +1 -0
- package/dist/cli/types.js.map +1 -1
- package/dist/cli/use-execute-steps.js.map +1 -1
- package/dist/cli/use-messages.js.map +1 -1
- package/dist/cli/use-nodemon.d.ts +14 -0
- package/dist/cli/use-nodemon.js +72 -52
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/cli/use-open-browser.d.ts +1 -0
- package/dist/cli/use-open-browser.js +44 -0
- package/dist/cli/use-open-browser.js.map +1 -0
- package/dist/cli/use-tunnel.d.ts +1 -1
- package/dist/cli/use-tunnel.js +102 -68
- package/dist/cli/use-tunnel.js.map +1 -1
- package/dist/cli/use-typescript-check.d.ts +9 -2
- package/dist/cli/use-typescript-check.js +89 -51
- package/dist/cli/use-typescript-check.js.map +1 -1
- package/dist/commands/build.d.ts +0 -3
- package/dist/commands/build.js +3 -19
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/create.d.ts +9 -0
- package/dist/commands/create.js +30 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +2 -0
- package/dist/commands/dev.js +81 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.js +7 -1
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/telemetry/disable.js.map +1 -1
- package/dist/commands/telemetry/enable.js.map +1 -1
- package/dist/commands/telemetry/status.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.d.ts +1 -0
- package/dist/server/asset-base-url-transform-plugin.js +17 -2
- package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.test.js +80 -1
- package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
- package/dist/server/auth/discovery.d.ts +32 -0
- package/dist/server/auth/discovery.js +56 -0
- package/dist/server/auth/discovery.js.map +1 -0
- package/dist/server/auth/discovery.test.d.ts +1 -0
- package/dist/server/auth/discovery.test.js +93 -0
- package/dist/server/auth/discovery.test.js.map +1 -0
- package/dist/server/auth/index.d.ts +18 -0
- package/dist/server/auth/index.js +2 -0
- package/dist/server/auth/index.js.map +1 -0
- package/dist/server/auth/providers/auth0.d.ts +18 -0
- package/dist/server/auth/providers/auth0.js +31 -0
- package/dist/server/auth/providers/auth0.js.map +1 -0
- package/dist/server/auth/providers/auth0.test.d.ts +1 -0
- package/dist/server/auth/providers/auth0.test.js +48 -0
- package/dist/server/auth/providers/auth0.test.js.map +1 -0
- package/dist/server/auth/providers/clerk.d.ts +14 -0
- package/dist/server/auth/providers/clerk.js +16 -0
- package/dist/server/auth/providers/clerk.js.map +1 -0
- package/dist/server/auth/providers/clerk.test.d.ts +1 -0
- package/dist/server/auth/providers/clerk.test.js +28 -0
- package/dist/server/auth/providers/clerk.test.js.map +1 -0
- package/dist/server/auth/providers/custom.d.ts +30 -0
- package/dist/server/auth/providers/custom.js +40 -0
- package/dist/server/auth/providers/custom.js.map +1 -0
- package/dist/server/auth/providers/custom.test.d.ts +1 -0
- package/dist/server/auth/providers/custom.test.js +128 -0
- package/dist/server/auth/providers/custom.test.js.map +1 -0
- package/dist/server/auth/providers/descope.d.ts +15 -0
- package/dist/server/auth/providers/descope.js +35 -0
- package/dist/server/auth/providers/descope.js.map +1 -0
- package/dist/server/auth/providers/descope.test.d.ts +1 -0
- package/dist/server/auth/providers/descope.test.js +39 -0
- package/dist/server/auth/providers/descope.test.js.map +1 -0
- package/dist/server/auth/providers/shared.d.ts +2 -0
- package/dist/server/auth/providers/shared.js +6 -0
- package/dist/server/auth/providers/shared.js.map +1 -0
- package/dist/server/auth/providers/shared.test.d.ts +1 -0
- package/dist/server/auth/providers/shared.test.js +10 -0
- package/dist/server/auth/providers/shared.test.js.map +1 -0
- package/dist/server/auth/providers/stytch.d.ts +12 -0
- package/dist/server/auth/providers/stytch.js +13 -0
- package/dist/server/auth/providers/stytch.js.map +1 -0
- package/dist/server/auth/providers/workos.d.ts +11 -0
- package/dist/server/auth/providers/workos.js +12 -0
- package/dist/server/auth/providers/workos.js.map +1 -0
- 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 +6 -0
- package/dist/server/auth/setup.js +92 -0
- package/dist/server/auth/setup.js.map +1 -0
- package/dist/server/auth/setup.test.d.ts +1 -0
- package/dist/server/auth/setup.test.js +474 -0
- package/dist/server/auth/setup.test.js.map +1 -0
- package/dist/server/auth/verify.d.ts +12 -0
- package/dist/server/auth/verify.js +38 -0
- package/dist/server/auth/verify.js.map +1 -0
- package/dist/server/auth/verify.test.d.ts +1 -0
- package/dist/server/auth/verify.test.js +100 -0
- package/dist/server/auth/verify.test.js.map +1 -0
- package/dist/server/auth.d.ts +20 -0
- package/dist/server/auth.js +28 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/build-manifest.test.d.ts +1 -0
- package/dist/server/build-manifest.test.js +27 -0
- package/dist/server/build-manifest.test.js.map +1 -0
- package/dist/server/content-helpers.d.ts +40 -0
- package/dist/server/content-helpers.js +33 -0
- package/dist/server/content-helpers.js.map +1 -1
- package/dist/server/content-helpers.test.js +1 -1
- package/dist/server/content-helpers.test.js.map +1 -1
- package/dist/server/express.d.ts +1 -5
- package/dist/server/express.js +34 -10
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +310 -71
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/file-ref.d.ts +28 -0
- package/dist/server/file-ref.js +27 -0
- package/dist/server/file-ref.js.map +1 -0
- 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 +13 -3
- package/dist/server/index.js +11 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/inferUtilityTypes.d.ts +6 -6
- package/dist/server/inferUtilityTypes.js.map +1 -1
- package/dist/server/metric.js.map +1 -1
- package/dist/server/middleware.d.ts +16 -3
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/middleware.test-d.js.map +1 -1
- package/dist/server/middleware.test.js.map +1 -1
- package/dist/server/requestOrigin.d.ts +7 -0
- package/dist/server/requestOrigin.js +25 -0
- package/dist/server/requestOrigin.js.map +1 -0
- package/dist/server/server.d.ts +322 -41
- package/dist/server/server.js +557 -213
- 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 +63 -0
- package/dist/server/skills-integration.test.js.map +1 -0
- package/dist/server/skills.d.ts +23 -0
- package/dist/server/skills.js +178 -0
- package/dist/server/skills.js.map +1 -0
- package/dist/server/skills.test.d.ts +1 -0
- package/dist/server/skills.test.js +210 -0
- package/dist/server/skills.test.js.map +1 -0
- package/dist/server/templateHelper.d.ts +5 -7
- package/dist/server/templateHelper.js +3 -22
- package/dist/server/templateHelper.js.map +1 -1
- package/dist/server/templates.generated.d.ts +4 -0
- package/dist/server/templates.generated.js +47 -0
- package/dist/server/templates.generated.js.map +1 -0
- package/dist/server/tunnel-proxy-router.d.ts +7 -0
- package/dist/server/tunnel-proxy-router.js +110 -0
- package/dist/server/tunnel-proxy-router.js.map +1 -0
- package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
- package/dist/server/tunnel-proxy-router.test.js +229 -0
- package/dist/server/tunnel-proxy-router.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.d.ts +6 -0
- package/dist/server/view-resource-resolution.test.js +171 -0
- package/dist/server/view-resource-resolution.test.js.map +1 -0
- package/dist/server/viewsDevServer.d.ts +14 -0
- package/dist/server/{widgetsDevServer.js → viewsDevServer.js} +11 -9
- package/dist/server/viewsDevServer.js.map +1 -0
- package/dist/test/utils.d.ts +7 -7
- package/dist/test/utils.js +21 -21
- package/dist/test/utils.js.map +1 -1
- package/dist/test/view.test.d.ts +1 -0
- package/dist/test/{widget.test.js → view.test.js} +206 -124
- package/dist/test/view.test.js.map +1 -0
- package/dist/version.js +1 -3
- package/dist/version.js.map +1 -1
- package/dist/web/bridges/adaptor.d.ts +51 -0
- package/dist/web/bridges/adaptor.js +330 -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 +208 -0
- package/dist/web/bridges/adaptor.test.js.map +1 -0
- package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
- package/dist/web/bridges/apps-sdk/bridge.js +15 -3
- 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/types.d.ts +8 -1
- package/dist/web/bridges/apps-sdk/types.js.map +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
- package/dist/web/bridges/get-adaptor.d.ts +7 -0
- package/dist/web/bridges/get-adaptor.js +9 -7
- 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/index.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
- package/dist/web/bridges/mcp-app/bridge.js +68 -4
- 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.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +12 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
- 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.map +1 -1
- package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
- package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
- package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
- package/dist/web/bridges/types.d.ts +115 -10
- 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/bridges/use-host-context.d.ts +5 -0
- package/dist/web/bridges/use-host-context.js +5 -0
- package/dist/web/bridges/use-host-context.js.map +1 -1
- 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.d.ts +26 -0
- package/dist/web/create-store.js +35 -9
- package/dist/web/create-store.js.map +1 -1
- package/dist/web/create-store.test.js +22 -21
- package/dist/web/create-store.test.js.map +1 -1
- package/dist/web/data-llm.d.ts +35 -2
- package/dist/web/data-llm.js +31 -3
- package/dist/web/data-llm.js.map +1 -1
- package/dist/web/data-llm.test.js +39 -27
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/generate-helpers.d.ts +16 -14
- package/dist/web/generate-helpers.js +16 -14
- package/dist/web/generate-helpers.js.map +1 -1
- package/dist/web/generate-helpers.test-d.js +30 -28
- package/dist/web/generate-helpers.test-d.js.map +1 -1
- package/dist/web/generate-helpers.test.js.map +1 -1
- package/dist/web/helpers/state.d.ts +2 -2
- package/dist/web/helpers/state.js +11 -11
- package/dist/web/helpers/state.js.map +1 -1
- package/dist/web/helpers/state.test.js +9 -9
- package/dist/web/helpers/state.test.js.map +1 -1
- package/dist/web/hooks/index.d.ts +5 -1
- package/dist/web/hooks/index.js +5 -1
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/test/utils.d.ts +6 -2
- package/dist/web/hooks/test/utils.js +13 -2
- package/dist/web/hooks/test/utils.js.map +1 -1
- package/dist/web/hooks/use-call-tool.d.ts +45 -0
- package/dist/web/hooks/use-call-tool.js +28 -0
- package/dist/web/hooks/use-call-tool.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test.js +62 -27
- package/dist/web/hooks/use-call-tool.test.js.map +1 -1
- package/dist/web/hooks/use-display-mode.d.ts +20 -0
- package/dist/web/hooks/use-display-mode.js +20 -0
- package/dist/web/hooks/use-display-mode.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test.js +56 -20
- package/dist/web/hooks/use-display-mode.test.js.map +1 -1
- package/dist/web/hooks/use-download.d.ts +5 -0
- package/dist/web/hooks/use-download.js +8 -0
- package/dist/web/hooks/use-download.js.map +1 -0
- package/dist/web/hooks/use-download.test.d.ts +1 -0
- package/dist/web/hooks/use-download.test.js +103 -0
- package/dist/web/hooks/use-download.test.js.map +1 -0
- package/dist/web/hooks/use-files.d.ts +32 -0
- package/dist/web/hooks/use-files.js +32 -0
- package/dist/web/hooks/use-files.js.map +1 -1
- package/dist/web/hooks/use-files.test.js +10 -2
- package/dist/web/hooks/use-files.test.js.map +1 -1
- package/dist/web/hooks/use-layout.d.ts +2 -0
- package/dist/web/hooks/use-layout.js +2 -0
- package/dist/web/hooks/use-layout.js.map +1 -1
- package/dist/web/hooks/use-layout.test.js +59 -26
- package/dist/web/hooks/use-layout.test.js.map +1 -1
- package/dist/web/hooks/use-open-external.d.ts +17 -0
- package/dist/web/hooks/use-open-external.js +16 -0
- package/dist/web/hooks/use-open-external.js.map +1 -1
- package/dist/web/hooks/use-open-external.test.js +13 -3
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
- package/dist/web/hooks/use-register-view-tool.js +50 -0
- package/dist/web/hooks/use-register-view-tool.js.map +1 -0
- package/dist/web/hooks/use-request-close.d.ts +16 -0
- package/dist/web/hooks/use-request-close.js +21 -0
- package/dist/web/hooks/use-request-close.js.map +1 -0
- package/dist/web/hooks/use-request-close.test.d.ts +1 -0
- package/dist/web/hooks/use-request-close.test.js +47 -0
- package/dist/web/hooks/use-request-close.test.js.map +1 -0
- package/dist/web/hooks/use-request-modal.d.ts +16 -1
- package/dist/web/hooks/use-request-modal.js +19 -4
- package/dist/web/hooks/use-request-modal.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 +20 -0
- package/dist/web/hooks/use-request-size.js +24 -0
- package/dist/web/hooks/use-request-size.js.map +1 -0
- package/dist/web/hooks/use-request-size.test.d.ts +1 -0
- package/dist/web/hooks/use-request-size.test.js +47 -0
- package/dist/web/hooks/use-request-size.test.js.map +1 -0
- package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -1
- package/dist/web/hooks/use-send-follow-up-message.js +19 -2
- package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
- package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
- package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.test.js +28 -8
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
- package/dist/web/hooks/use-tool-info.d.ts +53 -2
- package/dist/web/hooks/use-tool-info.js +30 -7
- package/dist/web/hooks/use-tool-info.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test-d.js +11 -29
- package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js +42 -32
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.d.ts +2 -0
- package/dist/web/hooks/use-user.js +2 -0
- package/dist/web/hooks/use-user.js.map +1 -1
- package/dist/web/hooks/use-user.test.js +81 -35
- package/dist/web/hooks/use-user.test.js.map +1 -1
- package/dist/web/hooks/use-view-state.d.ts +25 -0
- package/dist/web/hooks/use-view-state.js +32 -0
- package/dist/web/hooks/use-view-state.js.map +1 -0
- package/dist/web/hooks/use-view-state.test.d.ts +1 -0
- package/dist/web/hooks/{use-widget-state.test.js → use-view-state.test.js} +23 -19
- package/dist/web/hooks/use-view-state.test.js.map +1 -0
- package/dist/web/index.d.ts +1 -3
- package/dist/web/index.js +1 -2
- package/dist/web/index.js.map +1 -1
- package/dist/web/mount-view.d.ts +20 -0
- package/dist/web/{mount-widget.js → mount-view.js} +21 -2
- package/dist/web/mount-view.js.map +1 -0
- package/dist/web/plugin/data-llm.test.js.map +1 -1
- package/dist/web/plugin/plugin.d.ts +29 -1
- package/dist/web/plugin/plugin.js +119 -41
- package/dist/web/plugin/plugin.js.map +1 -1
- package/dist/web/plugin/scan-views.d.ts +16 -0
- package/dist/web/plugin/scan-views.js +88 -0
- package/dist/web/plugin/scan-views.js.map +1 -0
- package/dist/web/plugin/scan-views.test.d.ts +1 -0
- package/dist/web/plugin/scan-views.test.js +99 -0
- package/dist/web/plugin/scan-views.test.js.map +1 -0
- package/dist/web/plugin/transform-data-llm.js.map +1 -1
- package/dist/web/plugin/transform-data-llm.test.js.map +1 -1
- package/dist/web/plugin/{validate-widget.js → validate-view.js} +1 -1
- package/dist/web/plugin/validate-view.js.map +1 -0
- package/dist/web/plugin/validate-view.test.d.ts +1 -0
- package/dist/web/plugin/{validate-widget.test.js → validate-view.test.js} +6 -6
- package/dist/web/plugin/validate-view.test.js.map +1 -0
- package/dist/web/proxy.js.map +1 -1
- package/dist/web/types.d.ts +4 -0
- package/dist/web/types.js.map +1 -1
- package/package.json +38 -24
- package/dist/server/templates/development.hbs +0 -12
- package/dist/server/templates/production.hbs +0 -6
- package/dist/server/widgetsDevServer.d.ts +0 -14
- package/dist/server/widgetsDevServer.js.map +0 -1
- package/dist/test/widget.test.js.map +0 -1
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -24
- package/dist/web/bridges/apps-sdk/adaptor.js +0 -87
- package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -48
- package/dist/web/bridges/mcp-app/adaptor.js +0 -268
- package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
- package/dist/web/hooks/use-widget-state.d.ts +0 -4
- package/dist/web/hooks/use-widget-state.js +0 -32
- package/dist/web/hooks/use-widget-state.js.map +0 -1
- package/dist/web/hooks/use-widget-state.test.js.map +0 -1
- package/dist/web/mount-widget.d.ts +0 -1
- package/dist/web/mount-widget.js.map +0 -1
- package/dist/web/plugin/scan-widgets.d.ts +0 -8
- package/dist/web/plugin/scan-widgets.js +0 -68
- package/dist/web/plugin/scan-widgets.js.map +0 -1
- package/dist/web/plugin/scan-widgets.test.js +0 -96
- package/dist/web/plugin/scan-widgets.test.js.map +0 -1
- package/dist/web/plugin/validate-widget.js.map +0 -1
- package/dist/web/plugin/validate-widget.test.js.map +0 -1
- /package/dist/{test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
- /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/build-steps.test.d.ts} +0 -0
- /package/dist/{web/plugin/scan-widgets.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
- /package/dist/{web/plugin/validate-widget.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
- /package/dist/web/plugin/{validate-widget.d.ts → validate-view.d.ts} +0 -0
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
|
+
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
2
4
|
import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
|
|
5
|
+
import { McpServer as McpServerClass } from "../server/server.js";
|
|
3
6
|
import { createMockExtra, createMockMcpServer, resetTestEnv, setTestEnv, } from "./utils.js";
|
|
4
7
|
const mockManifest = {
|
|
5
|
-
"skybridge:
|
|
6
|
-
file: "assets/my-
|
|
7
|
-
name: "my-
|
|
8
|
+
"skybridge:view:my-view": {
|
|
9
|
+
file: "assets/my-view-abc123.js",
|
|
10
|
+
name: "my-view",
|
|
8
11
|
isEntry: true,
|
|
9
12
|
},
|
|
10
|
-
"skybridge:
|
|
11
|
-
file: "assets/folder-
|
|
12
|
-
name: "folder-
|
|
13
|
+
"skybridge:view:folder-view": {
|
|
14
|
+
file: "assets/folder-view-def456.js",
|
|
15
|
+
name: "folder-view",
|
|
13
16
|
isEntry: true,
|
|
14
17
|
},
|
|
15
18
|
"style.css": { file: "style.css" },
|
|
16
19
|
};
|
|
20
|
+
// Mirrors `McpServer.computeViewVersionParam`. Tests recompute the expected
|
|
21
|
+
// hash from the mocked manifest so they don't hardcode digest output.
|
|
22
|
+
function expectedVersionParam(viewFile, styleFile) {
|
|
23
|
+
const hash = crypto
|
|
24
|
+
.createHash("sha256")
|
|
25
|
+
.update(viewFile)
|
|
26
|
+
.update("\0")
|
|
27
|
+
.update(styleFile)
|
|
28
|
+
.digest("hex")
|
|
29
|
+
.slice(0, 8);
|
|
30
|
+
return `?v=${hash}`;
|
|
31
|
+
}
|
|
17
32
|
const actual = vi.hoisted(() => require("node:fs"));
|
|
18
33
|
vi.mock("node:fs", () => {
|
|
19
34
|
const readFileSyncImpl = (path, ...args) => {
|
|
@@ -45,11 +60,11 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
45
60
|
it("should generate correct HTML for development mode", async () => {
|
|
46
61
|
setTestEnv({ NODE_ENV: "development" });
|
|
47
62
|
server.registerTool({
|
|
48
|
-
name: "my-
|
|
63
|
+
name: "my-view",
|
|
49
64
|
description: "Test tool",
|
|
50
65
|
view: {
|
|
51
|
-
component: "my-
|
|
52
|
-
description: "Test
|
|
66
|
+
component: "my-view",
|
|
67
|
+
description: "Test view",
|
|
53
68
|
},
|
|
54
69
|
}, vi.fn());
|
|
55
70
|
const appsSdkResourceCallback = mockRegisterResource.mock
|
|
@@ -59,37 +74,41 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
59
74
|
const serverUrl = `http://${host}`;
|
|
60
75
|
const hmrUrl = `ws://${host}`;
|
|
61
76
|
const mockExtra = createMockExtra(host);
|
|
62
|
-
const result = await appsSdkResourceCallback(new URL("ui://
|
|
77
|
+
const result = await appsSdkResourceCallback(new URL("ui://views/ext-apps/my-view.html"), mockExtra);
|
|
63
78
|
expect(mockRegisterTool).toHaveBeenCalled();
|
|
64
79
|
expect(result).toEqual({
|
|
65
80
|
contents: [
|
|
66
81
|
{
|
|
67
|
-
uri: "ui://
|
|
68
|
-
mimeType: "text/html
|
|
82
|
+
uri: "ui://views/ext-apps/my-view.html",
|
|
83
|
+
mimeType: "text/html;profile=mcp-app",
|
|
69
84
|
text: expect.stringContaining('<div id="root"></div>'),
|
|
70
85
|
_meta: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
86
|
+
ui: {
|
|
87
|
+
csp: {
|
|
88
|
+
resourceDomains: [serverUrl],
|
|
89
|
+
connectDomains: [serverUrl, hmrUrl],
|
|
90
|
+
baseUriDomains: [serverUrl],
|
|
91
|
+
},
|
|
92
|
+
domain: serverUrl,
|
|
93
|
+
description: "Test view",
|
|
74
94
|
},
|
|
75
|
-
"openai/
|
|
76
|
-
"openai/widgetDescription": "Test widget",
|
|
95
|
+
"openai/widgetDescription": "Test view",
|
|
77
96
|
},
|
|
78
97
|
},
|
|
79
98
|
],
|
|
80
99
|
});
|
|
81
100
|
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/@react-refresh`);
|
|
82
101
|
expect(result.contents[0]?.text).toContain(`${serverUrl}/@vite/client`);
|
|
83
|
-
expect(result.contents[0]?.text).toContain(`${serverUrl}/_skybridge/
|
|
102
|
+
expect(result.contents[0]?.text).toContain(`${serverUrl}/_skybridge/view/my-view`);
|
|
84
103
|
});
|
|
85
104
|
it("should generate correct HTML for production mode", async () => {
|
|
86
105
|
setTestEnv({ NODE_ENV: "production" });
|
|
87
106
|
server.registerTool({
|
|
88
|
-
name: "my-
|
|
107
|
+
name: "my-view",
|
|
89
108
|
description: "Test tool",
|
|
90
109
|
view: {
|
|
91
|
-
component: "my-
|
|
92
|
-
description: "Test
|
|
110
|
+
component: "my-view",
|
|
111
|
+
description: "Test view",
|
|
93
112
|
},
|
|
94
113
|
}, vi.fn());
|
|
95
114
|
const appsSdkResourceCallback = mockRegisterResource.mock
|
|
@@ -98,38 +117,43 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
98
117
|
const host = "myapp.com";
|
|
99
118
|
const serverUrl = `https://${host}`;
|
|
100
119
|
const mockExtra = createMockExtra(host);
|
|
101
|
-
const
|
|
120
|
+
const versionedUri = `ui://views/ext-apps/my-view.html${expectedVersionParam("assets/my-view-abc123.js", "style.css")}`;
|
|
121
|
+
const result = await appsSdkResourceCallback(new URL(versionedUri), mockExtra);
|
|
102
122
|
expect(result).toEqual({
|
|
103
123
|
contents: [
|
|
104
124
|
{
|
|
105
|
-
uri:
|
|
106
|
-
mimeType: "text/html
|
|
125
|
+
uri: versionedUri,
|
|
126
|
+
mimeType: "text/html;profile=mcp-app",
|
|
107
127
|
text: expect.stringContaining('<div id="root"></div>'),
|
|
108
128
|
_meta: {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
129
|
+
ui: {
|
|
130
|
+
csp: {
|
|
131
|
+
resourceDomains: [serverUrl],
|
|
132
|
+
connectDomains: [serverUrl],
|
|
133
|
+
baseUriDomains: [serverUrl],
|
|
134
|
+
},
|
|
135
|
+
domain: serverUrl,
|
|
136
|
+
description: "Test view",
|
|
112
137
|
},
|
|
113
|
-
"openai/
|
|
114
|
-
"openai/widgetDescription": "Test widget",
|
|
138
|
+
"openai/widgetDescription": "Test view",
|
|
115
139
|
},
|
|
116
140
|
},
|
|
117
141
|
],
|
|
118
142
|
});
|
|
119
143
|
expect(result.contents[0]?.text).not.toContain(`${serverUrl}/assets/@react-refresh`);
|
|
120
144
|
expect(result.contents[0]?.text).not.toContain(`${serverUrl}@vite/client`);
|
|
121
|
-
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/assets/my-
|
|
145
|
+
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/assets/my-view-abc123.js`);
|
|
122
146
|
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/style.css`);
|
|
123
147
|
});
|
|
124
|
-
it("should prefer x-alpic-forwarded-url when hashing Claude
|
|
148
|
+
it("should prefer x-alpic-forwarded-url when hashing Claude view domains", async () => {
|
|
125
149
|
setTestEnv({ NODE_ENV: "production" });
|
|
126
150
|
server.registerTool({
|
|
127
|
-
name: "my-
|
|
151
|
+
name: "my-view",
|
|
128
152
|
description: "Test tool",
|
|
129
|
-
view: { component: "my-
|
|
153
|
+
view: { component: "my-view", description: "Test view" },
|
|
130
154
|
}, vi.fn());
|
|
131
155
|
const extAppsResourceCallback = mockRegisterResource.mock
|
|
132
|
-
.calls[
|
|
156
|
+
.calls[0]?.[3];
|
|
133
157
|
expect(extAppsResourceCallback).toBeDefined();
|
|
134
158
|
const forwardedUrl = "https://everything-3a2c1264.staging.alpic.live/mcp?foo=bar";
|
|
135
159
|
const expectedDomain = `${crypto
|
|
@@ -137,7 +161,7 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
137
161
|
.update(forwardedUrl)
|
|
138
162
|
.digest("hex")
|
|
139
163
|
.slice(0, 32)}.claudemcpcontent.com`;
|
|
140
|
-
const result = await extAppsResourceCallback(new URL(
|
|
164
|
+
const result = await extAppsResourceCallback(new URL(`ui://views/ext-apps/my-view.html${expectedVersionParam("assets/my-view-abc123.js", "style.css")}`), createMockExtra("localhost:3000", {
|
|
141
165
|
headers: {
|
|
142
166
|
"user-agent": "Claude-User",
|
|
143
167
|
"x-alpic-forwarded-url": forwardedUrl,
|
|
@@ -151,55 +175,33 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
151
175
|
connectDomains: ["http://localhost:3000"],
|
|
152
176
|
baseUriDomains: ["http://localhost:3000"],
|
|
153
177
|
},
|
|
154
|
-
description: "Test
|
|
178
|
+
description: "Test view",
|
|
155
179
|
domain: expectedDomain,
|
|
156
180
|
},
|
|
181
|
+
"openai/widgetDescription": "Test view",
|
|
157
182
|
});
|
|
158
183
|
});
|
|
159
|
-
it("should register
|
|
184
|
+
it("should register a single ext-apps resource", async () => {
|
|
160
185
|
server.registerTool({
|
|
161
|
-
name: "my-
|
|
186
|
+
name: "my-view",
|
|
162
187
|
description: "Test tool",
|
|
163
188
|
view: {
|
|
164
|
-
component: "my-
|
|
165
|
-
description: "Test
|
|
189
|
+
component: "my-view",
|
|
190
|
+
description: "Test view",
|
|
166
191
|
prefersBorder: true,
|
|
167
192
|
},
|
|
168
193
|
}, vi.fn());
|
|
169
|
-
expect(mockRegisterResource).toHaveBeenCalledTimes(
|
|
170
|
-
const
|
|
194
|
+
expect(mockRegisterResource).toHaveBeenCalledTimes(1);
|
|
195
|
+
const resourceCallback = mockRegisterResource.mock
|
|
171
196
|
.calls[0]?.[3];
|
|
172
197
|
const host = "localhost:3000";
|
|
173
198
|
const serverUrl = `http://${host}`;
|
|
174
199
|
const hmrUrl = `ws://${host}`;
|
|
175
|
-
const
|
|
176
|
-
expect(
|
|
177
|
-
contents: [
|
|
178
|
-
{
|
|
179
|
-
uri: "ui://widgets/apps-sdk/my-widget.html",
|
|
180
|
-
mimeType: "text/html+skybridge",
|
|
181
|
-
text: expect.stringContaining('<div id="root"></div>'),
|
|
182
|
-
_meta: {
|
|
183
|
-
"openai/widgetCSP": {
|
|
184
|
-
resource_domains: [serverUrl],
|
|
185
|
-
connect_domains: [serverUrl, hmrUrl],
|
|
186
|
-
},
|
|
187
|
-
"openai/widgetDomain": serverUrl,
|
|
188
|
-
"openai/widgetDescription": "Test widget",
|
|
189
|
-
"openai/widgetPrefersBorder": true,
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
],
|
|
193
|
-
});
|
|
194
|
-
expect(appsSdkResult.contents[0]?.text).toContain('window.skybridge = { hostType: "apps-sdk", serverUrl: "http://localhost:3000" };');
|
|
195
|
-
const extAppsResourceCallback = mockRegisterResource.mock
|
|
196
|
-
.calls[1]?.[3];
|
|
197
|
-
expect(extAppsResourceCallback).toBeDefined();
|
|
198
|
-
const extAppsResult = await extAppsResourceCallback(new URL("ui://widgets/ext-apps/my-widget.html"), createMockExtra(host));
|
|
199
|
-
expect(extAppsResult).toEqual({
|
|
200
|
+
const result = await resourceCallback(new URL("ui://views/ext-apps/my-view.html"), createMockExtra(host));
|
|
201
|
+
expect(result).toEqual({
|
|
200
202
|
contents: [
|
|
201
203
|
{
|
|
202
|
-
uri: "ui://
|
|
204
|
+
uri: "ui://views/ext-apps/my-view.html",
|
|
203
205
|
mimeType: "text/html;profile=mcp-app",
|
|
204
206
|
text: expect.stringContaining('<div id="root"></div>'),
|
|
205
207
|
_meta: {
|
|
@@ -210,63 +212,96 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
210
212
|
baseUriDomains: [serverUrl],
|
|
211
213
|
},
|
|
212
214
|
domain: serverUrl,
|
|
213
|
-
description: "Test
|
|
215
|
+
description: "Test view",
|
|
214
216
|
prefersBorder: true,
|
|
215
217
|
},
|
|
218
|
+
"openai/widgetDescription": "Test view",
|
|
216
219
|
},
|
|
217
220
|
},
|
|
218
221
|
],
|
|
219
222
|
});
|
|
220
|
-
expect(
|
|
223
|
+
expect(result.contents[0]?.text).toContain('window.skybridge = { hostType: "mcp-app", serverUrl: "http://localhost:3000" };');
|
|
221
224
|
});
|
|
222
|
-
it("should
|
|
225
|
+
it("should advertise the single resource via ui.resourceUri only (no openai/outputTemplate)", async () => {
|
|
223
226
|
server.registerTool({
|
|
224
|
-
name: "my-
|
|
227
|
+
name: "my-view",
|
|
225
228
|
description: "Test tool",
|
|
226
|
-
view: { component: "my-
|
|
229
|
+
view: { component: "my-view", description: "Test view" },
|
|
227
230
|
}, vi.fn());
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
expect(toolConfig._meta
|
|
232
|
-
expect(toolConfig._meta?.
|
|
233
|
-
resourceUri: "ui://widgets/ext-apps/my-widget.html",
|
|
234
|
-
});
|
|
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();
|
|
235
236
|
});
|
|
236
|
-
it("
|
|
237
|
+
it("treats the deprecated hosts option as a no-op (always the single resource)", async () => {
|
|
237
238
|
server.registerTool({
|
|
238
|
-
name: "my-
|
|
239
|
+
name: "my-view",
|
|
239
240
|
description: "Test tool",
|
|
240
241
|
view: {
|
|
241
|
-
component: "my-
|
|
242
|
-
description: "Test
|
|
242
|
+
component: "my-view",
|
|
243
|
+
description: "Test view",
|
|
243
244
|
hosts: ["apps-sdk"],
|
|
244
245
|
},
|
|
245
246
|
}, vi.fn());
|
|
246
|
-
expect(
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
expect(toolConfig._meta).
|
|
250
|
-
expect(toolConfig._meta?.["openai/outputTemplate"]).toBe("ui://widgets/apps-sdk/my-widget.html");
|
|
247
|
+
expect(mockRegisterResource).toHaveBeenCalledTimes(1);
|
|
248
|
+
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
249
|
+
expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/my-view.html");
|
|
250
|
+
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
251
251
|
});
|
|
252
|
-
it("should
|
|
252
|
+
it("should not version view URIs in development", () => {
|
|
253
253
|
server.registerTool({
|
|
254
|
-
name: "my-
|
|
254
|
+
name: "my-view",
|
|
255
255
|
description: "Test tool",
|
|
256
|
-
view: {
|
|
257
|
-
component: "my-widget",
|
|
258
|
-
description: "Test widget",
|
|
259
|
-
hosts: ["mcp-app"],
|
|
260
|
-
},
|
|
256
|
+
view: { component: "my-view", description: "Test view" },
|
|
261
257
|
}, vi.fn());
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
258
|
+
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
259
|
+
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
260
|
+
expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/my-view.html");
|
|
261
|
+
// The URI registered with the resource handler must match ui.resourceUri
|
|
262
|
+
// exactly so the SDK can resolve `resources/read` requests.
|
|
263
|
+
expect(mockRegisterResource.mock.calls[0]?.[1]).toBe("ui://views/ext-apps/my-view.html");
|
|
264
|
+
});
|
|
265
|
+
it("should append a stable content hash to view URIs in production", () => {
|
|
266
|
+
setTestEnv({ NODE_ENV: "production" });
|
|
267
|
+
server.registerTool({
|
|
268
|
+
name: "my-view",
|
|
269
|
+
description: "Test tool",
|
|
270
|
+
view: { component: "my-view", description: "Test view" },
|
|
271
|
+
}, vi.fn());
|
|
272
|
+
const expected = expectedVersionParam("assets/my-view-abc123.js", "style.css");
|
|
273
|
+
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
269
274
|
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
275
|
+
expect(toolConfig._meta?.ui?.resourceUri).toBe(`ui://views/ext-apps/my-view.html${expected}`);
|
|
276
|
+
expect(mockRegisterResource.mock.calls[0]?.[1]).toBe(`ui://views/ext-apps/my-view.html${expected}`);
|
|
277
|
+
});
|
|
278
|
+
it("should produce different version params for views with different bundles", () => {
|
|
279
|
+
setTestEnv({ NODE_ENV: "production" });
|
|
280
|
+
server.registerTool({
|
|
281
|
+
name: "my-view",
|
|
282
|
+
description: "First tool",
|
|
283
|
+
view: { component: "my-view" },
|
|
284
|
+
}, vi.fn());
|
|
285
|
+
server.registerTool({
|
|
286
|
+
name: "folder-view",
|
|
287
|
+
description: "Second tool",
|
|
288
|
+
view: { component: "folder-view" },
|
|
289
|
+
}, vi.fn());
|
|
290
|
+
const myviewTemplate = mockRegisterTool.mock.calls[0][1]._meta?.ui?.resourceUri;
|
|
291
|
+
const folderviewTemplate = mockRegisterTool.mock.calls[1][1]._meta?.ui?.resourceUri;
|
|
292
|
+
expect(myviewTemplate).not.toEqual(folderviewTemplate);
|
|
293
|
+
expect(myviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
|
|
294
|
+
expect(folderviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
|
|
295
|
+
});
|
|
296
|
+
it("should fall back to bare URI in production when manifest is missing", () => {
|
|
297
|
+
setTestEnv({ NODE_ENV: "production" });
|
|
298
|
+
server.registerTool({
|
|
299
|
+
name: "unknown-view",
|
|
300
|
+
description: "Test tool",
|
|
301
|
+
view: { component: "unknown-view" },
|
|
302
|
+
}, vi.fn());
|
|
303
|
+
const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
|
|
304
|
+
expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/unknown-view.html");
|
|
270
305
|
});
|
|
271
306
|
it("should inject viewUUID into _meta of tool callback results", async () => {
|
|
272
307
|
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
@@ -274,9 +309,9 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
274
309
|
structuredContent: { data: "test" },
|
|
275
310
|
});
|
|
276
311
|
server.registerTool({
|
|
277
|
-
name: "my-
|
|
312
|
+
name: "my-view",
|
|
278
313
|
description: "Test tool",
|
|
279
|
-
view: { component: "my-
|
|
314
|
+
view: { component: "my-view", description: "Test view" },
|
|
280
315
|
}, mockToolCallback);
|
|
281
316
|
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
282
317
|
expect(wrappedCallback).toBeDefined();
|
|
@@ -293,9 +328,9 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
293
328
|
_meta: { requestId: "req-123", cached: true },
|
|
294
329
|
});
|
|
295
330
|
server.registerTool({
|
|
296
|
-
name: "my-
|
|
331
|
+
name: "my-view",
|
|
297
332
|
description: "Test tool",
|
|
298
|
-
view: { component: "my-
|
|
333
|
+
view: { component: "my-view", description: "Test view" },
|
|
299
334
|
}, mockToolCallback);
|
|
300
335
|
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
301
336
|
const result = await wrappedCallback({}, {});
|
|
@@ -309,16 +344,16 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
309
344
|
structuredContent: {},
|
|
310
345
|
});
|
|
311
346
|
server.registerTool({
|
|
312
|
-
name: "my-
|
|
347
|
+
name: "my-view",
|
|
313
348
|
description: "Test tool",
|
|
314
|
-
view: { component: "my-
|
|
349
|
+
view: { component: "my-view", description: "Test view" },
|
|
315
350
|
}, mockToolCallback);
|
|
316
351
|
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
317
352
|
const result1 = await wrappedCallback({}, {});
|
|
318
353
|
const result2 = await wrappedCallback({}, {});
|
|
319
354
|
expect(result1._meta?.viewUUID).not.toBe(result2._meta?.viewUUID);
|
|
320
355
|
});
|
|
321
|
-
it("should enforce one-tool-per-
|
|
356
|
+
it("should enforce one-tool-per-view constraint", () => {
|
|
322
357
|
server.registerTool({
|
|
323
358
|
name: "shake",
|
|
324
359
|
description: "First tool",
|
|
@@ -330,7 +365,7 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
330
365
|
description: "Second tool",
|
|
331
366
|
view: { component: "magic-8-ball" },
|
|
332
367
|
}, vi.fn());
|
|
333
|
-
}).toThrow('skybridge:
|
|
368
|
+
}).toThrow('skybridge: view "magic-8-ball" is already used by tool "shake"');
|
|
334
369
|
});
|
|
335
370
|
it("should normalize string content to ContentBlock array", async () => {
|
|
336
371
|
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
@@ -381,7 +416,7 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
381
416
|
it("should register tool without view (no resource registration)", () => {
|
|
382
417
|
server.registerTool({
|
|
383
418
|
name: "plain-tool",
|
|
384
|
-
description: "No
|
|
419
|
+
description: "No view",
|
|
385
420
|
}, vi.fn());
|
|
386
421
|
expect(mockRegisterResource).not.toHaveBeenCalled();
|
|
387
422
|
expect(mockRegisterTool).toHaveBeenCalledTimes(1);
|
|
@@ -392,7 +427,7 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
392
427
|
description: "Test tool",
|
|
393
428
|
view: {
|
|
394
429
|
component: "csp-tool",
|
|
395
|
-
description: "Test
|
|
430
|
+
description: "Test view",
|
|
396
431
|
csp: {
|
|
397
432
|
connectDomains: ["https://api.example.com"],
|
|
398
433
|
resourceDomains: ["https://cdn.example.com"],
|
|
@@ -404,11 +439,12 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
404
439
|
const host = "localhost:3000";
|
|
405
440
|
const serverUrl = `http://${host}`;
|
|
406
441
|
const hmrUrl = `ws://${host}`;
|
|
407
|
-
const result = await appsSdkCallback(new URL("ui://
|
|
442
|
+
const result = await appsSdkCallback(new URL("ui://views/ext-apps/csp-tool.html"), createMockExtra(host));
|
|
408
443
|
const meta = result.contents[0]?._meta;
|
|
409
|
-
expect(meta
|
|
410
|
-
|
|
411
|
-
|
|
444
|
+
expect(meta.ui?.csp).toEqual({
|
|
445
|
+
resourceDomains: [serverUrl, "https://cdn.example.com"],
|
|
446
|
+
connectDomains: [serverUrl, hmrUrl, "https://api.example.com"],
|
|
447
|
+
baseUriDomains: [serverUrl],
|
|
412
448
|
});
|
|
413
449
|
});
|
|
414
450
|
it("should let view._meta override framework-computed keys", async () => {
|
|
@@ -417,21 +453,23 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
417
453
|
description: "Test tool",
|
|
418
454
|
view: {
|
|
419
455
|
component: "override-tool",
|
|
420
|
-
description: "Test
|
|
456
|
+
description: "Test view",
|
|
421
457
|
csp: { connectDomains: ["https://api.x.com"] },
|
|
422
458
|
_meta: {
|
|
423
|
-
|
|
424
|
-
|
|
459
|
+
ui: {
|
|
460
|
+
csp: {
|
|
461
|
+
connectDomains: ["https://api.y.com"],
|
|
462
|
+
},
|
|
425
463
|
},
|
|
426
464
|
},
|
|
427
465
|
},
|
|
428
466
|
}, vi.fn());
|
|
429
467
|
const appsSdkCallback = mockRegisterResource.mock
|
|
430
468
|
.calls[0]?.[3];
|
|
431
|
-
const result = await appsSdkCallback(new URL("ui://
|
|
469
|
+
const result = await appsSdkCallback(new URL("ui://views/ext-apps/override-tool.html"), createMockExtra("localhost:3000"));
|
|
432
470
|
const meta = result.contents[0]?._meta;
|
|
433
|
-
expect(meta
|
|
434
|
-
|
|
471
|
+
expect(meta.ui?.csp).toEqual({
|
|
472
|
+
connectDomains: ["https://api.y.com"],
|
|
435
473
|
});
|
|
436
474
|
});
|
|
437
475
|
it("should pass user _meta keys through to tool config", () => {
|
|
@@ -451,4 +489,48 @@ describe("McpServer.registerTool (unified API)", () => {
|
|
|
451
489
|
expect(toolConfig._meta?.["acme.com/category"]).toBe("utility");
|
|
452
490
|
});
|
|
453
491
|
});
|
|
454
|
-
|
|
492
|
+
describe("resources/list view _meta injection", () => {
|
|
493
|
+
afterEach(() => resetTestEnv());
|
|
494
|
+
it("attaches CSP, domain, and connectDomains _meta to view resources at list time", async () => {
|
|
495
|
+
setTestEnv({ NODE_ENV: "production" });
|
|
496
|
+
const server = new McpServerClass({ name: "test", version: "1.0.0" }, { capabilities: {} });
|
|
497
|
+
server.registerTool({
|
|
498
|
+
name: "start",
|
|
499
|
+
description: "Start",
|
|
500
|
+
view: {
|
|
501
|
+
component: "my-view",
|
|
502
|
+
description: "Onboarding deck",
|
|
503
|
+
domain: "skybridge.tech",
|
|
504
|
+
csp: {
|
|
505
|
+
resourceDomains: ["https://fonts.googleapis.com"],
|
|
506
|
+
redirectDomains: ["https://docs.skybridge.tech"],
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
}, vi.fn().mockResolvedValue({
|
|
510
|
+
content: [{ type: "text", text: "ok" }],
|
|
511
|
+
structuredContent: {},
|
|
512
|
+
}));
|
|
513
|
+
const client = new Client({ name: "test-client", version: "1.0.0" });
|
|
514
|
+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
515
|
+
await server.connect(serverTransport);
|
|
516
|
+
await client.connect(clientTransport);
|
|
517
|
+
const { resources } = await client.listResources();
|
|
518
|
+
await client.close();
|
|
519
|
+
await server.close();
|
|
520
|
+
const appsSdk = resources.find((r) => r.uri.includes("apps-sdk"));
|
|
521
|
+
const extApps = resources.find((r) => r.uri.includes("ext-apps"));
|
|
522
|
+
expect(appsSdk).toBeUndefined();
|
|
523
|
+
expect(extApps?._meta).toBeDefined();
|
|
524
|
+
const extUi = extApps._meta?.ui;
|
|
525
|
+
expect(extUi?.csp?.connectDomains?.length).toBeGreaterThan(0);
|
|
526
|
+
expect(extUi?.csp?.resourceDomains).toContain("https://fonts.googleapis.com");
|
|
527
|
+
expect(extUi?.domain).toBe("skybridge.tech");
|
|
528
|
+
const meta = extApps?._meta;
|
|
529
|
+
expect(meta["openai/widgetDescription"]).toBe("Onboarding deck");
|
|
530
|
+
expect(meta["openai/widgetCSP"]?.redirect_domains).toEqual([
|
|
531
|
+
"https://docs.skybridge.tech",
|
|
532
|
+
]);
|
|
533
|
+
expect(meta.ui?.csp).not.toHaveProperty("redirectDomains");
|
|
534
|
+
});
|
|
535
|
+
});
|
|
536
|
+
//# sourceMappingURL=view.test.js.map
|