skybridge 0.0.0-dev.efb7a49 → 0.0.0-dev.efba8c5
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 +126 -128
- package/dist/cli/build-helpers.d.ts +11 -0
- package/dist/cli/build-helpers.js +107 -0
- package/dist/cli/build-helpers.js.map +1 -0
- package/dist/cli/build-helpers.test.js +132 -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 +8 -20
- package/dist/cli/detect-port.js.map +1 -1
- package/dist/cli/header.d.ts +1 -1
- package/dist/cli/header.js +1 -1
- package/dist/cli/header.js.map +1 -1
- package/dist/cli/resolve-skybridge-config.d.ts +5 -0
- package/dist/cli/resolve-skybridge-config.js +18 -0
- package/dist/cli/resolve-skybridge-config.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.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.d.ts +1 -1
- package/dist/cli/use-execute-steps.js.map +1 -1
- package/dist/cli/use-messages.d.ts +3 -0
- package/dist/cli/use-messages.js +11 -0
- package/dist/cli/use-messages.js.map +1 -0
- package/dist/cli/use-nodemon.d.ts +16 -2
- package/dist/cli/use-nodemon.js +84 -72
- 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 +13 -7
- package/dist/cli/use-tunnel.js +103 -73
- 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 -18
- 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 +3 -0
- package/dist/commands/dev.js +90 -6
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.js +13 -10
- 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/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.d.ts +1 -0
- package/dist/server/app.test.js +97 -0
- package/dist/server/app.test.js.map +1 -0
- package/dist/server/asset-base-url-transform-plugin.d.ts +6 -6
- package/dist/server/asset-base-url-transform-plugin.js +25 -11
- package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.test.js +92 -14
- package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
- package/dist/server/auth/discovery.d.ts +33 -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 +48 -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 +40 -0
- package/dist/server/auth/providers/auth0.js +36 -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 +50 -0
- package/dist/server/auth/providers/auth0.test.js.map +1 -0
- 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.d.ts +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 +51 -0
- package/dist/server/auth/providers/clerk.js +19 -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 +30 -0
- package/dist/server/auth/providers/clerk.test.js.map +1 -0
- package/dist/server/auth/providers/custom.d.ts +40 -0
- package/dist/server/auth/providers/custom.js +59 -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 +161 -0
- package/dist/server/auth/providers/custom.test.js.map +1 -0
- package/dist/server/auth/providers/descope.d.ts +44 -0
- package/dist/server/auth/providers/descope.js +44 -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 +62 -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 +25 -0
- package/dist/server/auth/providers/stytch.js +16 -0
- package/dist/server/auth/providers/stytch.js.map +1 -0
- 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 +33 -0
- package/dist/server/auth/providers/workos.js +15 -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 +91 -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 +514 -0
- package/dist/server/auth/setup.test.js.map +1 -0
- package/dist/server/auth/verify.d.ts +46 -0
- package/dist/server/auth/verify.js +62 -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 +149 -0
- package/dist/server/auth/verify.test.js.map +1 -0
- package/dist/server/auth-extra.test-d.d.ts +1 -0
- 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 +57 -0
- package/dist/server/auth.js +27 -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 +28 -0
- package/dist/server/build-manifest.test.js.map +1 -0
- package/dist/server/content-helpers.d.ts +67 -0
- package/dist/server/content-helpers.js +79 -0
- package/dist/server/content-helpers.js.map +1 -0
- package/dist/server/content-helpers.test.d.ts +1 -0
- package/dist/server/content-helpers.test.js +70 -0
- package/dist/server/content-helpers.test.js.map +1 -0
- package/dist/server/express.d.ts +23 -7
- package/dist/server/express.js +62 -32
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +429 -73
- 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 +20 -3
- package/dist/server/index.js +17 -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/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/metric.d.ts +14 -0
- package/dist/server/metric.js +62 -0
- package/dist/server/metric.js.map +1 -0
- package/dist/server/middleware.d.ts +51 -13
- 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 -131
- 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/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 +359 -89
- package/dist/server/server.js +488 -230
- 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 +2 -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 +43 -0
- package/dist/server/templates.generated.js.map +1 -0
- 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/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 +176 -0
- package/dist/server/view-resource-resolution.test.js.map +1 -0
- package/dist/server/viewsDevServer.d.ts +14 -0
- package/dist/server/viewsDevServer.js +48 -0
- package/dist/server/viewsDevServer.js.map +1 -0
- package/dist/test/utils.d.ts +21 -31
- package/dist/test/utils.js +222 -198
- package/dist/test/utils.js.map +1 -1
- package/dist/test/view.test.d.ts +1 -0
- package/dist/test/view.test.js +540 -0
- package/dist/test/view.test.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- 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/views/scan-views.d.ts +16 -0
- package/dist/views/scan-views.js +88 -0
- 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 +99 -0
- package/dist/views/scan-views.test.js.map +1 -0
- package/dist/views/validate-view.d.ts +1 -0
- package/dist/views/validate-view.js +9 -0
- 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 +24 -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 -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 +18 -6
- 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 +73 -7
- 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 +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 +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 +127 -11
- 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 +43 -3
- package/dist/web/create-store.js.map +1 -1
- package/dist/web/create-store.test.js +24 -23
- 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 +42 -29
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/generate-helpers.d.ts +39 -31
- package/dist/web/generate-helpers.js +36 -28
- package/dist/web/generate-helpers.js.map +1 -1
- package/dist/web/generate-helpers.test-d.js +33 -31
- 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/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 +7 -2
- package/dist/web/hooks/index.js +7 -2
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/test/utils.d.ts +7 -2
- package/dist/web/hooks/test/utils.js +14 -3
- 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 +64 -29
- 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 +57 -21
- package/dist/web/hooks/use-display-mode.test.js.map +1 -1
- package/dist/web/hooks/use-download.d.ts +3 -0
- package/dist/web/hooks/use-download.js +7 -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 +34 -1
- package/dist/web/hooks/use-files.js +33 -0
- package/dist/web/hooks/use-files.js.map +1 -1
- package/dist/web/hooks/use-files.test.js +31 -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.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 +15 -5
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-register-view-tool.d.ts +37 -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 +12 -2
- 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 +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 +46 -14
- package/dist/web/hooks/use-tool-info.js +29 -7
- package/dist/web/hooks/use-tool-info.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test-d.js +11 -34
- package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js +42 -37
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.d.ts +5 -2
- package/dist/web/hooks/use-user.js +6 -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.d.ts +25 -0
- package/dist/web/hooks/use-view-state.js +42 -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-view-state.test.js +212 -0
- package/dist/web/hooks/use-view-state.test.js.map +1 -0
- 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/index.d.ts +1 -2
- package/dist/web/index.js +1 -2
- package/dist/web/index.js.map +1 -1
- package/dist/web/mount-view.d.ts +21 -0
- package/dist/web/mount-view.js +43 -0
- package/dist/web/mount-view.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 +46 -26
- package/tsconfig.base.json +2 -0
- package/dist/server/templates/development.hbs +0 -12
- package/dist/server/templates/production.hbs +0 -6
- package/dist/server/widgetsDevServer.d.ts +0 -13
- package/dist/server/widgetsDevServer.js +0 -57
- package/dist/server/widgetsDevServer.js.map +0 -1
- package/dist/test/widget.test.js +0 -263
- package/dist/test/widget.test.js.map +0 -1
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -22
- package/dist/web/bridges/apps-sdk/adaptor.js +0 -75
- package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -38
- package/dist/web/bridges/mcp-app/adaptor.js +0 -184
- package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
- package/dist/web/hooks/use-layout.d.ts +0 -22
- package/dist/web/hooks/use-layout.js +0 -23
- 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/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 +0 -64
- 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 +0 -27
- package/dist/web/mount-widget.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 -2
- package/dist/web/plugin/plugin.js +0 -54
- package/dist/web/plugin/plugin.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-widget.d.ts +0 -5
- package/dist/web/plugin/validate-widget.js +0 -27
- package/dist/web/plugin/validate-widget.js.map +0 -1
- package/dist/web/plugin/validate-widget.test.js +0 -42
- 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-layout.test.d.ts → cli/build-steps.test.d.ts} +0 -0
- /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
- /package/dist/{web/plugin/data-llm.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
- /package/dist/{web/plugin/transform-data-llm.test.d.ts → cli/tunnel.test.d.ts} +0 -0
- /package/dist/{web/plugin/validate-widget.test.d.ts → context-warnings.test.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-helpers.test.js","sourceRoot":"","sources":["../../src/cli/build-helpers.test.ts"],"names":[],"mappings":"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","sourcesContent":["// @vitest-environment node\n// esbuild's invariant check on TextEncoder/Uint8Array trips jsdom's polyfill.\nimport {\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { describe, expect, it } from \"vitest\";\nimport {\n ENTRY_WRAPPER_CONTENT,\n emitEmptyManifestModule,\n emitEntryWrapper,\n emitManifestModule,\n emitSkillsModule,\n emitVercelBuildOutput,\n ensureAssetsDir,\n VERCEL_CONFIG,\n VERCEL_VC_CONFIG,\n} from \"./build-helpers.js\";\n\nfunction mkTmp(prefix = \"skybridge-build-helpers-\") {\n return mkdtempSync(path.join(tmpdir(), prefix));\n}\n\ndescribe(\"emitEntryWrapper\", () => {\n it(\"writes dist/__entry.js that primes the manifest before importing user code\", () => {\n const dir = mkTmp();\n emitEntryWrapper(dir);\n const out = readFileSync(path.join(dir, \"__entry.js\"), \"utf-8\");\n expect(out).toBe(ENTRY_WRAPPER_CONTENT);\n expect(out).toContain(\n 'import { __setBuildManifest, __setSkillsManifest } from \"skybridge/server\"',\n );\n expect(out).toContain('import manifest from \"./vite-manifest.js\"');\n expect(out).toContain('import skills from \"./skills.js\"');\n expect(out).toContain(\"__setBuildManifest(manifest)\");\n expect(out).toContain(\"__setSkillsManifest(skills)\");\n // Dynamic import is load-bearing: `index.js` must evaluate after the\n // setters run, so a static re-export wouldn't work.\n expect(out).toContain('await import(\"./index.js\")');\n expect(out).toContain(\"export default userMod.default\");\n });\n});\n\ndescribe(\"emitSkillsModule\", () => {\n it(\"inlines discovered skills as an ESM default export\", () => {\n const dir = mkTmp();\n const skillsDir = path.join(dir, \"src\", \"skills\");\n mkdirSync(path.join(skillsDir, \"refunds\"), { recursive: true });\n writeFileSync(\n path.join(skillsDir, \"refunds\", \"SKILL.md\"),\n \"---\\nname: refunds\\ndescription: Process refunds\\n---\\nBody\",\n );\n const outPath = path.join(dir, \"skills.js\");\n emitSkillsModule(skillsDir, outPath);\n const out = readFileSync(outPath, \"utf-8\");\n const literal = out\n .slice(\"export default \".length)\n .trim()\n .replace(/;$/, \"\");\n const skills = JSON.parse(literal);\n expect(skills).toHaveLength(1);\n expect(skills[0]).toMatchObject({\n uri: \"skill://refunds/SKILL.md\",\n frontmatter: { name: \"refunds\", description: \"Process refunds\" },\n });\n expect(skills[0].resources).toHaveLength(1);\n expect(skills[0].resources[0].uri).toBe(\"skill://refunds/SKILL.md\");\n expect(skills[0].resources[0].digest).toMatch(/^sha256:[a-f0-9]{64}$/);\n });\n\n it(\"emits an empty array when the skills directory is absent\", () => {\n const dir = mkTmp();\n const outPath = path.join(dir, \"skills.js\");\n emitSkillsModule(path.join(dir, \"nope\"), outPath);\n expect(readFileSync(outPath, \"utf-8\")).toBe(\"export default [];\\n\");\n });\n});\n\ndescribe(\"emitManifestModule\", () => {\n it(\"inlines the JSON manifest as an ESM default export\", () => {\n const dir = mkTmp();\n const inPath = path.join(dir, \"manifest.json\");\n const outPath = path.join(dir, \"vite-manifest.js\");\n const manifest = { \"src/views/foo.tsx\": { file: \"assets/foo-abc.js\" } };\n writeFileSync(inPath, JSON.stringify(manifest));\n emitManifestModule(inPath, outPath);\n const out = readFileSync(outPath, \"utf-8\");\n expect(out.startsWith(\"export default \")).toBe(true);\n const literal = out\n .slice(\"export default \".length)\n .trim()\n .replace(/;$/, \"\");\n expect(JSON.parse(literal)).toEqual(manifest);\n });\n});\n\ndescribe(\"emitEmptyManifestModule\", () => {\n it(\"writes an empty object default export\", () => {\n const dir = mkTmp();\n const outPath = path.join(dir, \"vite-manifest.js\");\n emitEmptyManifestModule(outPath);\n expect(readFileSync(outPath, \"utf-8\")).toBe(\"export default {};\\n\");\n });\n});\n\ndescribe(\"ensureAssetsDir\", () => {\n it(\"creates the assets directory when missing\", () => {\n const dir = mkTmp();\n const assetsDir = path.join(dir, \"dist\", \"assets\");\n ensureAssetsDir(assetsDir);\n expect(existsSync(assetsDir)).toBe(true);\n });\n});\n\ndescribe(\"emitVercelBuildOutput\", () => {\n it(\"emits a Build Output API tree with bundled function and static assets\", async () => {\n const root = mkTmp();\n mkdirSync(path.join(root, \"dist\", \"assets\"), { recursive: true });\n writeFileSync(\n path.join(root, \"dist\", \"server.js\"),\n \"export default function handler(_req, res) { res.end('ok'); }\\n\",\n );\n // Minimal `dist/__entry.js` (the real wrapper imports `skybridge/server`,\n // which isn't resolvable in this test's tmp dir — the function-bundling\n // contract we care about here is just \"bundle whatever `__entry.js`\n // imports into a single function file\").\n writeFileSync(\n path.join(root, \"dist\", \"__entry.js\"),\n \"const userMod = await import('./server.js');\\nexport default userMod.default;\\n\",\n );\n writeFileSync(\n path.join(root, \"dist\", \"assets\", \"view-abc.js\"),\n \"/* bundled view */\\n\",\n );\n\n await emitVercelBuildOutput(root);\n\n const outputDir = path.join(root, \".vercel\", \"output\");\n const funcDir = path.join(outputDir, \"functions\", \"mcp.func\");\n\n expect(existsSync(path.join(funcDir, \"index.js\"))).toBe(true);\n expect(\n JSON.parse(readFileSync(path.join(funcDir, \".vc-config.json\"), \"utf-8\")),\n ).toEqual(VERCEL_VC_CONFIG);\n expect(\n JSON.parse(readFileSync(path.join(funcDir, \"package.json\"), \"utf-8\")),\n ).toEqual({ type: \"module\" });\n expect(\n JSON.parse(readFileSync(path.join(outputDir, \"config.json\"), \"utf-8\")),\n ).toEqual(VERCEL_CONFIG);\n expect(\n readFileSync(\n path.join(outputDir, \"static\", \"assets\", \"view-abc.js\"),\n \"utf-8\",\n ),\n ).toContain(\"bundled view\");\n });\n\n it(\"leaves serverExternal packages unbundled\", async () => {\n const root = mkTmp();\n mkdirSync(path.join(root, \"dist\"), { recursive: true });\n // Unresolvable from the tmp root, so esbuild fails the build unless the\n // package is marked external (bunyan → optional `dtrace-provider`).\n writeFileSync(\n path.join(root, \"dist\", \"__entry.js\"),\n 'import \"dtrace-provider\";\\nexport default null;\\n',\n );\n\n await expect(emitVercelBuildOutput(root)).rejects.toThrow(\n /Could not resolve \"dtrace-provider\"/,\n );\n await emitVercelBuildOutput(root, [\"dtrace-provider\"]);\n\n const bundle = readFileSync(\n path.join(root, \".vercel\", \"output\", \"functions\", \"mcp.func\", \"index.js\"),\n \"utf-8\",\n );\n expect(bundle).toContain('import \"dtrace-provider\"');\n });\n\n it(\"emits static assets directory when dist/assets is missing\", async () => {\n const root = mkTmp();\n mkdirSync(path.join(root, \"dist\"), { recursive: true });\n writeFileSync(\n path.join(root, \"dist\", \"__entry.js\"),\n \"const userMod = await import('./server.js');\\nexport default userMod.default;\\n\",\n );\n writeFileSync(\n path.join(root, \"dist\", \"server.js\"),\n \"export default function handler(_req, res) { res.end('ok'); }\\n\",\n );\n\n await emitVercelBuildOutput(root);\n\n expect(\n existsSync(path.join(root, \".vercel\", \"output\", \"static\", \"assets\")),\n ).toBe(true);\n expect(\n existsSync(\n path.join(\n root,\n \".vercel\",\n \"output\",\n \"functions\",\n \"mcp.func\",\n \"index.js\",\n ),\n ),\n ).toBe(true);\n });\n});\n"]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path, { isAbsolute, resolve } from "node:path";
|
|
3
|
+
import { scanAndWriteViewsDts, scanViewsSync } from "../views/index.js";
|
|
4
|
+
import { emitEmptyManifestModule, emitEntryWrapper, emitManifestModule, emitSkillsModule, emitVercelBuildOutput, ensureAssetsDir, } from "./build-helpers.js";
|
|
5
|
+
import { resolveSkybridgeConfig } from "./resolve-skybridge-config.js";
|
|
6
|
+
export async function getCommandSteps(root = process.cwd()) {
|
|
7
|
+
const { viewsDir, serverExternal } = await resolveSkybridgeConfig(root);
|
|
8
|
+
const rawDir = viewsDir ?? "src/views";
|
|
9
|
+
const resolvedDir = isAbsolute(rawDir) ? rawDir : resolve(root, rawDir);
|
|
10
|
+
// Non-throwing pre-check: duplicate view names are validated in the
|
|
11
|
+
// "Scanning views" step so useExecuteSteps can render a styled error.
|
|
12
|
+
const hasViews = scanViewsSync(resolvedDir).valid.length > 0;
|
|
13
|
+
const steps = [
|
|
14
|
+
{
|
|
15
|
+
label: "Scanning views",
|
|
16
|
+
run: async () => {
|
|
17
|
+
scanAndWriteViewsDts(root, viewsDir);
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
label: "Compiling server",
|
|
22
|
+
run: () => rmSync(path.join(root, "dist"), { recursive: true, force: true }),
|
|
23
|
+
command: "tsc -b --force",
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
if (hasViews) {
|
|
27
|
+
steps.push({
|
|
28
|
+
label: "Building views",
|
|
29
|
+
command: "vite build",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
steps.push({
|
|
33
|
+
label: "Emitting manifest module",
|
|
34
|
+
run: () => {
|
|
35
|
+
const manifestOut = path.join(root, "dist", "vite-manifest.js");
|
|
36
|
+
if (hasViews) {
|
|
37
|
+
emitManifestModule(path.join(root, "dist", "assets", ".vite", "manifest.json"), manifestOut);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
emitEmptyManifestModule(manifestOut);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
}, {
|
|
44
|
+
label: "Emitting skills module",
|
|
45
|
+
run: () => {
|
|
46
|
+
emitSkillsModule(resolve(root, "src/skills"), path.join(root, "dist", "skills.js"));
|
|
47
|
+
},
|
|
48
|
+
}, {
|
|
49
|
+
label: "Emitting entry wrapper",
|
|
50
|
+
run: () => {
|
|
51
|
+
emitEntryWrapper(path.join(root, "dist"));
|
|
52
|
+
},
|
|
53
|
+
}, {
|
|
54
|
+
label: "Emitting Cloudflare redirects",
|
|
55
|
+
run: () => {
|
|
56
|
+
const assetsDir = path.join(root, "dist", "assets");
|
|
57
|
+
ensureAssetsDir(assetsDir);
|
|
58
|
+
writeFileSync(path.join(assetsDir, "_redirects"), "/assets/assets/* /assets/:splat 200\n");
|
|
59
|
+
},
|
|
60
|
+
}, {
|
|
61
|
+
label: "Emitting Cloudflare headers",
|
|
62
|
+
run: () => {
|
|
63
|
+
const assetsDir = path.join(root, "dist", "assets");
|
|
64
|
+
ensureAssetsDir(assetsDir);
|
|
65
|
+
writeFileSync(path.join(assetsDir, "_headers"), "/assets/*\n Access-Control-Allow-Origin: *\n");
|
|
66
|
+
},
|
|
67
|
+
}, {
|
|
68
|
+
label: "Emitting Vercel build output",
|
|
69
|
+
run: () => emitVercelBuildOutput(root, serverExternal),
|
|
70
|
+
});
|
|
71
|
+
return steps;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=build-steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-steps.js","sourceRoot":"","sources":["../../src/cli/build-steps.ts"],"names":[],"mappings":"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","sourcesContent":["import { rmSync, writeFileSync } from \"node:fs\";\nimport path, { isAbsolute, resolve } from \"node:path\";\nimport { scanAndWriteViewsDts, scanViewsSync } from \"../views/index.js\";\nimport {\n emitEmptyManifestModule,\n emitEntryWrapper,\n emitManifestModule,\n emitSkillsModule,\n emitVercelBuildOutput,\n ensureAssetsDir,\n} from \"./build-helpers.js\";\nimport { resolveSkybridgeConfig } from \"./resolve-skybridge-config.js\";\nimport type { CommandStep } from \"./use-execute-steps.js\";\n\nexport async function getCommandSteps(\n root = process.cwd(),\n): Promise<CommandStep[]> {\n const { viewsDir, serverExternal } = await resolveSkybridgeConfig(root);\n const rawDir = viewsDir ?? \"src/views\";\n const resolvedDir = isAbsolute(rawDir) ? rawDir : resolve(root, rawDir);\n // Non-throwing pre-check: duplicate view names are validated in the\n // \"Scanning views\" step so useExecuteSteps can render a styled error.\n const hasViews = scanViewsSync(resolvedDir).valid.length > 0;\n\n const steps: CommandStep[] = [\n {\n label: \"Scanning views\",\n run: async () => {\n scanAndWriteViewsDts(root, viewsDir);\n },\n },\n {\n label: \"Compiling server\",\n run: () =>\n rmSync(path.join(root, \"dist\"), { recursive: true, force: true }),\n command: \"tsc -b --force\",\n },\n ];\n\n if (hasViews) {\n steps.push({\n label: \"Building views\",\n command: \"vite build\",\n });\n }\n\n steps.push(\n {\n label: \"Emitting manifest module\",\n run: () => {\n const manifestOut = path.join(root, \"dist\", \"vite-manifest.js\");\n if (hasViews) {\n emitManifestModule(\n path.join(root, \"dist\", \"assets\", \".vite\", \"manifest.json\"),\n manifestOut,\n );\n } else {\n emitEmptyManifestModule(manifestOut);\n }\n },\n },\n {\n label: \"Emitting skills module\",\n run: () => {\n emitSkillsModule(\n resolve(root, \"src/skills\"),\n path.join(root, \"dist\", \"skills.js\"),\n );\n },\n },\n {\n label: \"Emitting entry wrapper\",\n run: () => {\n emitEntryWrapper(path.join(root, \"dist\"));\n },\n },\n {\n label: \"Emitting Cloudflare redirects\",\n run: () => {\n const assetsDir = path.join(root, \"dist\", \"assets\");\n ensureAssetsDir(assetsDir);\n writeFileSync(\n path.join(assetsDir, \"_redirects\"),\n \"/assets/assets/* /assets/:splat 200\\n\",\n );\n },\n },\n {\n label: \"Emitting Cloudflare headers\",\n run: () => {\n const assetsDir = path.join(root, \"dist\", \"assets\");\n ensureAssetsDir(assetsDir);\n writeFileSync(\n path.join(assetsDir, \"_headers\"),\n \"/assets/*\\n Access-Control-Allow-Origin: *\\n\",\n );\n },\n },\n {\n label: \"Emitting Vercel build output\",\n run: () => emitVercelBuildOutput(root, serverExternal),\n },\n );\n\n return steps;\n}\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { describe, expect, it } from "vitest";
|
|
6
|
+
import { getCommandSteps } from "./build-steps.js";
|
|
7
|
+
function mkTmp(prefix = "skybridge-build-steps-") {
|
|
8
|
+
return mkdtempSync(path.join(tmpdir(), prefix));
|
|
9
|
+
}
|
|
10
|
+
describe("getCommandSteps", () => {
|
|
11
|
+
it("omits the vite build step when no views are registered", async () => {
|
|
12
|
+
const root = mkTmp();
|
|
13
|
+
mkdirSync(path.join(root, "src"), { recursive: true });
|
|
14
|
+
writeFileSync(path.join(root, "vite.config.ts"), `import { defineConfig } from "vite";
|
|
15
|
+
import { skybridge } from "@skybridge/vite-plugin";
|
|
16
|
+
export default defineConfig({ plugins: [skybridge()] });`);
|
|
17
|
+
writeFileSync(path.join(root, "tsconfig.json"), JSON.stringify({ compilerOptions: { strict: true } }));
|
|
18
|
+
const steps = await getCommandSteps(root);
|
|
19
|
+
const labels = steps.map((step) => step.label);
|
|
20
|
+
expect(labels).not.toContain("Building views");
|
|
21
|
+
expect(labels).toContain("Emitting manifest module");
|
|
22
|
+
expect(labels.at(-1)).toBe("Emitting Vercel build output");
|
|
23
|
+
});
|
|
24
|
+
it("includes the vite build step when views are present", async () => {
|
|
25
|
+
const root = mkTmp();
|
|
26
|
+
mkdirSync(path.join(root, "src", "views"), { recursive: true });
|
|
27
|
+
writeFileSync(path.join(root, "src", "views", "hello.tsx"), "export default function Hello() { return null; }\n");
|
|
28
|
+
writeFileSync(path.join(root, "vite.config.ts"), `import { defineConfig } from "vite";
|
|
29
|
+
import { skybridge } from "@skybridge/vite-plugin";
|
|
30
|
+
export default defineConfig({ plugins: [skybridge()] });`);
|
|
31
|
+
writeFileSync(path.join(root, "tsconfig.json"), JSON.stringify({ compilerOptions: { strict: true } }));
|
|
32
|
+
const steps = await getCommandSteps(root);
|
|
33
|
+
const labels = steps.map((step) => step.label);
|
|
34
|
+
expect(labels).toContain("Building views");
|
|
35
|
+
});
|
|
36
|
+
it("emits an empty manifest module when there are no views", async () => {
|
|
37
|
+
const root = mkTmp();
|
|
38
|
+
mkdirSync(path.join(root, "src"), { recursive: true });
|
|
39
|
+
writeFileSync(path.join(root, "vite.config.ts"), `import { defineConfig } from "vite";
|
|
40
|
+
import { skybridge } from "@skybridge/vite-plugin";
|
|
41
|
+
export default defineConfig({ plugins: [skybridge()] });`);
|
|
42
|
+
const steps = await getCommandSteps(root);
|
|
43
|
+
const emitManifest = steps.find((step) => step.label === "Emitting manifest module");
|
|
44
|
+
expect(emitManifest?.run).toBeDefined();
|
|
45
|
+
mkdirSync(path.join(root, "dist"), { recursive: true });
|
|
46
|
+
await emitManifest?.run?.();
|
|
47
|
+
const manifestOut = path.join(root, "dist", "vite-manifest.js");
|
|
48
|
+
expect(existsSync(manifestOut)).toBe(true);
|
|
49
|
+
expect(readFileSync(manifestOut, "utf-8")).toBe("export default {};\n");
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=build-steps.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-steps.test.js","sourceRoot":"","sources":["../../src/cli/build-steps.test.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EACL,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,SAAS,KAAK,CAAC,MAAM,GAAG,wBAAwB;IAC9C,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,EACjC;;yDAEmD,CACpD,CAAC;QACF,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAChC,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CACtD,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE/C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,EAC5C,oDAAoD,CACrD,CAAC;QACF,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,EACjC;;yDAEmD,CACpD,CAAC;QACF,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAChC,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CACtD,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;QACrB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,EACjC;;yDAEmD,CACpD,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAC7B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,0BAA0B,CACpD,CAAC;QACF,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAExC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,YAAY,EAAE,GAAG,EAAE,EAAE,CAAC;QAE5B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAChE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// @vitest-environment node\nimport {\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { describe, expect, it } from \"vitest\";\nimport { getCommandSteps } from \"./build-steps.js\";\n\nfunction mkTmp(prefix = \"skybridge-build-steps-\") {\n return mkdtempSync(path.join(tmpdir(), prefix));\n}\n\ndescribe(\"getCommandSteps\", () => {\n it(\"omits the vite build step when no views are registered\", async () => {\n const root = mkTmp();\n mkdirSync(path.join(root, \"src\"), { recursive: true });\n writeFileSync(\n path.join(root, \"vite.config.ts\"),\n `import { defineConfig } from \"vite\";\nimport { skybridge } from \"@skybridge/vite-plugin\";\nexport default defineConfig({ plugins: [skybridge()] });`,\n );\n writeFileSync(\n path.join(root, \"tsconfig.json\"),\n JSON.stringify({ compilerOptions: { strict: true } }),\n );\n\n const steps = await getCommandSteps(root);\n const labels = steps.map((step) => step.label);\n\n expect(labels).not.toContain(\"Building views\");\n expect(labels).toContain(\"Emitting manifest module\");\n expect(labels.at(-1)).toBe(\"Emitting Vercel build output\");\n });\n\n it(\"includes the vite build step when views are present\", async () => {\n const root = mkTmp();\n mkdirSync(path.join(root, \"src\", \"views\"), { recursive: true });\n writeFileSync(\n path.join(root, \"src\", \"views\", \"hello.tsx\"),\n \"export default function Hello() { return null; }\\n\",\n );\n writeFileSync(\n path.join(root, \"vite.config.ts\"),\n `import { defineConfig } from \"vite\";\nimport { skybridge } from \"@skybridge/vite-plugin\";\nexport default defineConfig({ plugins: [skybridge()] });`,\n );\n writeFileSync(\n path.join(root, \"tsconfig.json\"),\n JSON.stringify({ compilerOptions: { strict: true } }),\n );\n\n const steps = await getCommandSteps(root);\n const labels = steps.map((step) => step.label);\n\n expect(labels).toContain(\"Building views\");\n });\n\n it(\"emits an empty manifest module when there are no views\", async () => {\n const root = mkTmp();\n mkdirSync(path.join(root, \"src\"), { recursive: true });\n writeFileSync(\n path.join(root, \"vite.config.ts\"),\n `import { defineConfig } from \"vite\";\nimport { skybridge } from \"@skybridge/vite-plugin\";\nexport default defineConfig({ plugins: [skybridge()] });`,\n );\n\n const steps = await getCommandSteps(root);\n const emitManifest = steps.find(\n (step) => step.label === \"Emitting manifest module\",\n );\n expect(emitManifest?.run).toBeDefined();\n\n mkdirSync(path.join(root, \"dist\"), { recursive: true });\n await emitManifest?.run?.();\n\n const manifestOut = path.join(root, \"dist\", \"vite-manifest.js\");\n expect(existsSync(manifestOut)).toBe(true);\n expect(readFileSync(manifestOut, \"utf-8\")).toBe(\"export default {};\\n\");\n });\n});\n"]}
|
|
@@ -8,8 +8,8 @@ export declare function resolvePort(flagPort?: number): Promise<{
|
|
|
8
8
|
envWarning: string;
|
|
9
9
|
}>;
|
|
10
10
|
/**
|
|
11
|
-
* Returns the
|
|
12
|
-
*
|
|
11
|
+
* Returns the first available port at or after `startPort`, incrementing
|
|
12
|
+
* by one until a free port is found or `MAX_PORT_INCREMENT` is reached.
|
|
13
13
|
*
|
|
14
14
|
* @param host - Bind address for the check. Pass `"localhost"` for
|
|
15
15
|
* services that bind to 127.0.0.1 (e.g. Vite HMR). Omit for
|
package/dist/cli/detect-port.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import net from "node:net";
|
|
2
2
|
const DEFAULT_PORT = 3000;
|
|
3
|
+
const MAX_PORT_INCREMENT = 100;
|
|
3
4
|
export async function resolvePort(flagPort) {
|
|
4
5
|
if (flagPort && flagPort > 1) {
|
|
5
6
|
return { port: flagPort, fallback: false };
|
|
@@ -20,33 +21,20 @@ export async function resolvePort(flagPort) {
|
|
|
20
21
|
return { port, fallback: port !== DEFAULT_PORT };
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
|
-
* Returns the
|
|
24
|
-
*
|
|
24
|
+
* Returns the first available port at or after `startPort`, incrementing
|
|
25
|
+
* by one until a free port is found or `MAX_PORT_INCREMENT` is reached.
|
|
25
26
|
*
|
|
26
27
|
* @param host - Bind address for the check. Pass `"localhost"` for
|
|
27
28
|
* services that bind to 127.0.0.1 (e.g. Vite HMR). Omit for
|
|
28
29
|
* services that bind to all interfaces (e.g. the HTTP server).
|
|
29
30
|
*/
|
|
30
31
|
export async function detectAvailablePort(startPort, host) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
for (let port = startPort; port < startPort + MAX_PORT_INCREMENT; port++) {
|
|
33
|
+
if (await isPortAvailable(port, host)) {
|
|
34
|
+
return port;
|
|
35
|
+
}
|
|
34
36
|
}
|
|
35
|
-
|
|
36
|
-
const server = net.createServer();
|
|
37
|
-
server.once("error", reject);
|
|
38
|
-
server.once("listening", () => {
|
|
39
|
-
const addr = server.address();
|
|
40
|
-
if (addr && typeof addr === "object") {
|
|
41
|
-
const { port } = addr;
|
|
42
|
-
server.close(() => resolve(port));
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
server.close(() => reject(new Error("Failed to detect available port")));
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
server.listen(0, host);
|
|
49
|
-
});
|
|
37
|
+
throw new Error(`No available port found between ${startPort} and ${startPort + MAX_PORT_INCREMENT - 1}`);
|
|
50
38
|
}
|
|
51
39
|
function isPortAvailable(port, host) {
|
|
52
40
|
return new Promise((resolve) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect-port.js","sourceRoot":"","sources":["../../src/cli/detect-port.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,MAAM,YAAY,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"detect-port.js","sourceRoot":"","sources":["../../src/cli/detect-port.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,MAAM,YAAY,GAAG,IAAI,CAAC;AAC1B,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAiB;IACjD,IAAI,QAAQ,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO;YACL,IAAI,EAAE,MAAM,mBAAmB,CAAC,YAAY,CAAC;YAC7C,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,iBAAiB,MAAM,+BAA+B;SACnE,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACrD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;AACnD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,IAAa;IAEb,KAAK,IAAI,IAAI,GAAG,SAAS,EAAE,IAAI,GAAG,SAAS,GAAG,kBAAkB,EAAE,IAAI,EAAE,EAAE,CAAC;QACzE,IAAI,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CACb,mCAAmC,SAAS,QAAQ,SAAS,GAAG,kBAAkB,GAAG,CAAC,EAAE,CACzF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,IAAa;IAClD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAElC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import net from \"node:net\";\n\nconst DEFAULT_PORT = 3000;\nconst MAX_PORT_INCREMENT = 100;\n\nexport async function resolvePort(flagPort?: number) {\n if (flagPort && flagPort > 1) {\n return { port: flagPort, fallback: false };\n }\n\n const rawEnv = process.env.PORT;\n if (rawEnv) {\n const parsed = Number(rawEnv);\n if (Number.isInteger(parsed) && parsed > 0) {\n return { port: parsed, fallback: false };\n }\n return {\n port: await detectAvailablePort(DEFAULT_PORT),\n fallback: false,\n envWarning: `Invalid PORT=\"${rawEnv}\", ignoring and using default`,\n };\n }\n\n const port = await detectAvailablePort(DEFAULT_PORT);\n return { port, fallback: port !== DEFAULT_PORT };\n}\n\n/**\n * Returns the first available port at or after `startPort`, incrementing\n * by one until a free port is found or `MAX_PORT_INCREMENT` is reached.\n *\n * @param host - Bind address for the check. Pass `\"localhost\"` for\n * services that bind to 127.0.0.1 (e.g. Vite HMR). Omit for\n * services that bind to all interfaces (e.g. the HTTP server).\n */\nexport async function detectAvailablePort(\n startPort: number,\n host?: string,\n): Promise<number> {\n for (let port = startPort; port < startPort + MAX_PORT_INCREMENT; port++) {\n if (await isPortAvailable(port, host)) {\n return port;\n }\n }\n throw new Error(\n `No available port found between ${startPort} and ${startPort + MAX_PORT_INCREMENT - 1}`,\n );\n}\n\nfunction isPortAvailable(port: number, host?: string): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n\n server.once(\"error\", () => resolve(false));\n server.once(\"listening\", () => {\n server.close(() => resolve(true));\n });\n\n server.listen(port, host);\n });\n}\n"]}
|
package/dist/cli/header.d.ts
CHANGED
package/dist/cli/header.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
3
|
export const Header = ({ version, children, }) => {
|
|
4
|
-
return (_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\u26F0", " ", "
|
|
4
|
+
return (_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\u26F0", " ", "Skybridge"] }), _jsxs(Text, { color: "cyan", children: [" v", version] }), children] }));
|
|
5
5
|
};
|
|
6
6
|
//# sourceMappingURL=header.js.map
|
package/dist/cli/header.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/cli/header.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,OAAO,EACP,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO,CACL,MAAC,GAAG,IAAC,YAAY,EAAE,CAAC,aAClB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,6BACnB,IAAI,
|
|
1
|
+
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/cli/header.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,OAAO,EACP,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO,CACL,MAAC,GAAG,IAAC,YAAY,EAAE,CAAC,aAClB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,6BACnB,IAAI,iBACD,EACP,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,mBAAI,OAAO,IAAQ,EACpC,QAAQ,IACL,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { Box, Text } from \"ink\";\n\nexport const Header = ({\n version,\n children,\n}: {\n version: string;\n children?: React.ReactNode;\n}) => {\n return (\n <Box marginBottom={1}>\n <Text color=\"cyan\" bold>\n ⛰{\" \"}Skybridge\n </Text>\n <Text color=\"cyan\"> v{version}</Text>\n {children}\n </Box>\n );\n};\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export async function resolveSkybridgeConfig(root) {
|
|
2
|
+
const { loadConfigFromFile } = await import("vite");
|
|
3
|
+
const loaded = await loadConfigFromFile({ command: "build", mode: "production" }, undefined, root);
|
|
4
|
+
const isPluginCandidate = (value) => typeof value === "object" && value !== null;
|
|
5
|
+
const plugins = [];
|
|
6
|
+
const walk = (value) => {
|
|
7
|
+
if (Array.isArray(value)) {
|
|
8
|
+
value.forEach(walk);
|
|
9
|
+
}
|
|
10
|
+
else if (isPluginCandidate(value)) {
|
|
11
|
+
plugins.push(value);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
walk(loaded?.config.plugins ?? []);
|
|
15
|
+
const api = plugins.find((p) => p.name === "skybridge")?.api;
|
|
16
|
+
return { viewsDir: api?.viewsDir, serverExternal: api?.serverExternal };
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=resolve-skybridge-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-skybridge-config.js","sourceRoot":"","sources":["../../src/cli/resolve-skybridge-config.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAAY;IAEZ,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,EACxC,SAAS,EACT,IAAI,CACL,CAAC;IAEF,MAAM,iBAAiB,GAAG,CACxB,KAAc,EACqC,EAAE,CACrD,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;IAE9C,MAAM,OAAO,GAAoD,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE;QAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,GAAG,CAAC;IAC7D,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC;AAC1E,CAAC","sourcesContent":["export interface SkybridgeConfig {\n viewsDir?: string;\n serverExternal?: string[];\n}\n\nexport async function resolveSkybridgeConfig(\n root: string,\n): Promise<SkybridgeConfig> {\n const { loadConfigFromFile } = await import(\"vite\");\n const loaded = await loadConfigFromFile(\n { command: \"build\", mode: \"production\" },\n undefined,\n root,\n );\n\n const isPluginCandidate = (\n value: unknown,\n ): value is { name?: string; api?: SkybridgeConfig } =>\n typeof value === \"object\" && value !== null;\n\n const plugins: Array<{ name?: string; api?: SkybridgeConfig }> = [];\n const walk = (value: unknown) => {\n if (Array.isArray(value)) {\n value.forEach(walk);\n } else if (isPluginCandidate(value)) {\n plugins.push(value);\n }\n };\n walk(loaded?.config.plugins ?? []);\n const api = plugins.find((p) => p.name === \"skybridge\")?.api;\n return { viewsDir: api?.viewsDir, serverExternal: api?.serverExternal };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,UAAwB;IACtB,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;CACxC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE;YAC1B,GAAG,OAAO;YACV,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC5D,MAAM,SAAS,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC;qBAC3C,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;qBACjC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,MAAM,YAAY,GAAG,SAAS;oBAC5B,CAAC,CAAC,iCAAiC,IAAI,KAAK,SAAS,EAAE;oBACvD,CAAC,CAAC,iCAAiC,IAAI,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACzB,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,UAAwB;IACtB,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;CACxC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE;YAC1B,GAAG,OAAO;YACV,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC5D,MAAM,SAAS,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC;qBAC3C,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;qBACjC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,MAAM,YAAY,GAAG,SAAS;oBAC5B,CAAC,CAAC,iCAAiC,IAAI,KAAK,SAAS,EAAE;oBACvD,CAAC,CAAC,iCAAiC,IAAI,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACzB,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { type SpawnOptions, spawn } from \"node:child_process\";\n\nexport function runCommand(\n command: string,\n options: SpawnOptions = {\n stdio: [\"ignore\", \"inherit\", \"inherit\"],\n },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n const proc = spawn(command, {\n ...options,\n shell: true,\n });\n\n if (proc.stdout) {\n proc.stdout.on(\"data\", (chunk) => {\n stdoutChunks.push(chunk);\n });\n }\n\n if (proc.stderr) {\n proc.stderr.on(\"data\", (chunk) => {\n stderrChunks.push(chunk);\n });\n }\n\n proc.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n const stdoutOutput = Buffer.concat(stdoutChunks).toString();\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n const allOutput = [stdoutOutput, stderrOutput]\n .filter((output) => output.trim())\n .join(\"\\n\");\n const errorMessage = allOutput\n ? `Command failed with exit code ${code}\\n${allOutput}`\n : `Command failed with exit code ${code}`;\n reject(new Error(errorMessage));\n }\n });\n\n proc.on(\"error\", (error) => {\n reject(error);\n });\n });\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TunnelManager } from "./tunnel.js";
|
|
2
|
+
export interface RunPlainOptions {
|
|
3
|
+
env: NodeJS.ProcessEnv;
|
|
4
|
+
port: number;
|
|
5
|
+
fallback: boolean;
|
|
6
|
+
version: string;
|
|
7
|
+
tunnel: boolean;
|
|
8
|
+
tunnelManager: TunnelManager;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Run `skybridge dev` without the Ink UI. The server's stdout is forwarded
|
|
12
|
+
* verbatim to the real stdout so it can be piped through a formatter
|
|
13
|
+
* (`skybridge dev --plain | bunyan`); everything else (banner, URLs, tunnel
|
|
14
|
+
* state, TypeScript errors, restarts) is written to stderr.
|
|
15
|
+
*
|
|
16
|
+
* Returns a cleanup function that tears down nodemon and the tsc watcher.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runPlain(options: RunPlainOptions): () => void;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { startNodemon } from "./use-nodemon.js";
|
|
2
|
+
import { startTypeScriptCheck } from "./use-typescript-check.js";
|
|
3
|
+
// Banner/URLs/diagnostics go to stderr so a downstream pipe (e.g.
|
|
4
|
+
// `skybridge dev --plain | bunyan`) only ever sees the server's own stdout.
|
|
5
|
+
function info(message) {
|
|
6
|
+
process.stderr.write(`${message}\n`);
|
|
7
|
+
}
|
|
8
|
+
function describeTunnel(state, port) {
|
|
9
|
+
switch (state.status) {
|
|
10
|
+
case "starting":
|
|
11
|
+
return `🌍 ${state.message}`;
|
|
12
|
+
case "connected":
|
|
13
|
+
return `🌍 Exposed on ${state.url}/mcp\n→ Test with an LLM on Playground: ${state.url}/try`;
|
|
14
|
+
case "error":
|
|
15
|
+
return `🌍 Cannot open tunnel: ${state.message}\n→ Try manually: npx alpic tunnel --port ${port}`;
|
|
16
|
+
default:
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run `skybridge dev` without the Ink UI. The server's stdout is forwarded
|
|
22
|
+
* verbatim to the real stdout so it can be piped through a formatter
|
|
23
|
+
* (`skybridge dev --plain | bunyan`); everything else (banner, URLs, tunnel
|
|
24
|
+
* state, TypeScript errors, restarts) is written to stderr.
|
|
25
|
+
*
|
|
26
|
+
* Returns a cleanup function that tears down nodemon and the tsc watcher.
|
|
27
|
+
*/
|
|
28
|
+
export function runPlain(options) {
|
|
29
|
+
const { env, port, fallback, version, tunnel, tunnelManager } = options;
|
|
30
|
+
// If the downstream formatter (e.g. `| bunyan`) exits, the next write raises
|
|
31
|
+
// EPIPE. Swallow it so a closed pipe doesn't crash the dev server.
|
|
32
|
+
const ignoreEpipe = (err) => {
|
|
33
|
+
if (err.code !== "EPIPE") {
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
process.stdout.on("error", ignoreEpipe);
|
|
38
|
+
process.stderr.on("error", ignoreEpipe);
|
|
39
|
+
info(`⛰ Skybridge v${version}`);
|
|
40
|
+
info(fallback
|
|
41
|
+
? `🏠 3000 in use, running on http://localhost:${port}/mcp`
|
|
42
|
+
: `🏠 Running on http://localhost:${port}/mcp`);
|
|
43
|
+
info(`→ Test locally with DevTools: http://localhost:${port}/`);
|
|
44
|
+
if (!tunnel) {
|
|
45
|
+
info("🌍 Get a public URL and LLM Playground access with --tunnel.");
|
|
46
|
+
}
|
|
47
|
+
const stopNodemon = startNodemon(env, {
|
|
48
|
+
onStdout: (chunk) => process.stdout.write(chunk),
|
|
49
|
+
onStderr: (message) => info(message),
|
|
50
|
+
onRestart: (files) => info(`✓ Server restarted due to file changes: ${files.join(", ")}`),
|
|
51
|
+
});
|
|
52
|
+
let lastTsErrorKey = "";
|
|
53
|
+
const stopTypeScriptCheck = startTypeScriptCheck((errors) => {
|
|
54
|
+
// tsc re-emits on every save; only print when the error set actually changes.
|
|
55
|
+
const key = errors
|
|
56
|
+
.map((e) => `${e.file}:${e.line}:${e.col}:${e.message}`)
|
|
57
|
+
.join("|");
|
|
58
|
+
if (key === lastTsErrorKey) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
lastTsErrorKey = key;
|
|
62
|
+
if (errors.length === 0) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
info("⚠️ TypeScript errors found:");
|
|
66
|
+
for (const error of errors) {
|
|
67
|
+
info(` ${error.file}(${error.line},${error.col}): ${error.message}`);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const unsubscribeTunnel = tunnel
|
|
71
|
+
? tunnelManager.subscribe((state) => {
|
|
72
|
+
const message = describeTunnel(state, port);
|
|
73
|
+
if (message) {
|
|
74
|
+
info(message);
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
: () => { };
|
|
78
|
+
if (tunnel) {
|
|
79
|
+
tunnelManager.start();
|
|
80
|
+
}
|
|
81
|
+
return () => {
|
|
82
|
+
unsubscribeTunnel();
|
|
83
|
+
stopNodemon();
|
|
84
|
+
stopTypeScriptCheck();
|
|
85
|
+
process.stdout.off("error", ignoreEpipe);
|
|
86
|
+
process.stderr.off("error", ignoreEpipe);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=run-plain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-plain.js","sourceRoot":"","sources":["../../src/cli/run-plain.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TunnelManager, TunnelState } from \"./tunnel.js\";\nimport { startNodemon } from \"./use-nodemon.js\";\nimport { startTypeScriptCheck, type TsError } from \"./use-typescript-check.js\";\n\nexport interface RunPlainOptions {\n env: NodeJS.ProcessEnv;\n port: number;\n fallback: boolean;\n version: string;\n tunnel: boolean;\n tunnelManager: TunnelManager;\n}\n\n// Banner/URLs/diagnostics go to stderr so a downstream pipe (e.g.\n// `skybridge dev --plain | bunyan`) only ever sees the server's own stdout.\nfunction info(message: string): void {\n process.stderr.write(`${message}\\n`);\n}\n\nfunction describeTunnel(state: TunnelState, port: number): string {\n switch (state.status) {\n case \"starting\":\n return `🌍 ${state.message}`;\n case \"connected\":\n return `🌍 Exposed on ${state.url}/mcp\\n→ Test with an LLM on Playground: ${state.url}/try`;\n case \"error\":\n return `🌍 Cannot open tunnel: ${state.message}\\n→ Try manually: npx alpic tunnel --port ${port}`;\n default:\n return \"\";\n }\n}\n\n/**\n * Run `skybridge dev` without the Ink UI. The server's stdout is forwarded\n * verbatim to the real stdout so it can be piped through a formatter\n * (`skybridge dev --plain | bunyan`); everything else (banner, URLs, tunnel\n * state, TypeScript errors, restarts) is written to stderr.\n *\n * Returns a cleanup function that tears down nodemon and the tsc watcher.\n */\nexport function runPlain(options: RunPlainOptions): () => void {\n const { env, port, fallback, version, tunnel, tunnelManager } = options;\n\n // If the downstream formatter (e.g. `| bunyan`) exits, the next write raises\n // EPIPE. Swallow it so a closed pipe doesn't crash the dev server.\n const ignoreEpipe = (err: NodeJS.ErrnoException) => {\n if (err.code !== \"EPIPE\") {\n throw err;\n }\n };\n process.stdout.on(\"error\", ignoreEpipe);\n process.stderr.on(\"error\", ignoreEpipe);\n\n info(`⛰ Skybridge v${version}`);\n info(\n fallback\n ? `🏠 3000 in use, running on http://localhost:${port}/mcp`\n : `🏠 Running on http://localhost:${port}/mcp`,\n );\n info(`→ Test locally with DevTools: http://localhost:${port}/`);\n if (!tunnel) {\n info(\"🌍 Get a public URL and LLM Playground access with --tunnel.\");\n }\n\n const stopNodemon = startNodemon(env, {\n onStdout: (chunk) => process.stdout.write(chunk),\n onStderr: (message) => info(message),\n onRestart: (files) =>\n info(`✓ Server restarted due to file changes: ${files.join(\", \")}`),\n });\n\n let lastTsErrorKey = \"\";\n const stopTypeScriptCheck = startTypeScriptCheck((errors: Array<TsError>) => {\n // tsc re-emits on every save; only print when the error set actually changes.\n const key = errors\n .map((e) => `${e.file}:${e.line}:${e.col}:${e.message}`)\n .join(\"|\");\n if (key === lastTsErrorKey) {\n return;\n }\n lastTsErrorKey = key;\n if (errors.length === 0) {\n return;\n }\n info(\"⚠️ TypeScript errors found:\");\n for (const error of errors) {\n info(` ${error.file}(${error.line},${error.col}): ${error.message}`);\n }\n });\n\n const unsubscribeTunnel = tunnel\n ? tunnelManager.subscribe((state) => {\n const message = describeTunnel(state, port);\n if (message) {\n info(message);\n }\n })\n : () => {};\n\n if (tunnel) {\n tunnelManager.start();\n }\n\n return () => {\n unsubscribeTunnel();\n stopNodemon();\n stopTypeScriptCheck();\n process.stdout.off(\"error\", ignoreEpipe);\n process.stderr.off(\"error\", ignoreEpipe);\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/cli/telemetry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/cli/telemetry.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Hook } from \"@oclif/core\";\nimport ci from \"ci-info\";\nimport { PostHog } from \"posthog-node\";\n\nconst POSTHOG_API_KEY = \"phc_rQdkCYr0DO4NcZBQXZnUwsHAbau9zuNwKIpil9FQP6v\";\nconst POSTHOG_HOST = \"https://us.i.posthog.com\";\n\nconst ENV_TELEMETRY_DISABLED = \"SKYBRIDGE_TELEMETRY_DISABLED\";\nconst ENV_TELEMETRY_DEBUG = \"SKYBRIDGE_TELEMETRY_DEBUG\";\nconst ENV_DO_NOT_TRACK = \"DO_NOT_TRACK\";\n\nconst GLOBAL_CONFIG_DIR = join(homedir(), \".skybridge\");\nconst GLOBAL_CONFIG_FILE = join(GLOBAL_CONFIG_DIR, \"config.json\");\n\ninterface GlobalConfig {\n machineId: string;\n telemetry: {\n enabled: boolean;\n };\n}\n\ninterface TelemetryEvent {\n version: string;\n machineId: string;\n sessionId: string;\n isCI: boolean;\n nodeVersion: string;\n platform: NodeJS.Platform;\n outcome: \"success\" | \"failure\";\n error?: string;\n}\n\nlet posthogClient: PostHog | null = null;\n\nfunction getPostHogClient(): PostHog {\n if (!posthogClient) {\n posthogClient = new PostHog(POSTHOG_API_KEY, {\n host: POSTHOG_HOST,\n flushAt: 1,\n flushInterval: 0,\n });\n }\n\n return posthogClient;\n}\n\nfunction readJsonFile<T>(filePath: string): T | null {\n try {\n if (existsSync(filePath)) {\n const content = readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n }\n } catch {\n // Ignore errors reading config\n }\n return null;\n}\n\nfunction writeJsonFile(filePath: string, data: unknown): void {\n try {\n const dir = join(filePath, \"..\");\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf-8\");\n } catch {\n // Ignore errors writing config\n }\n}\n\nfunction getGlobalConfig(): GlobalConfig {\n const existing = readJsonFile<GlobalConfig>(GLOBAL_CONFIG_FILE);\n if (existing?.machineId && existing?.telemetry !== undefined) {\n return existing;\n }\n\n const config: GlobalConfig = {\n machineId: existing?.machineId || crypto.randomUUID(),\n telemetry: {\n enabled: existing?.telemetry?.enabled ?? true,\n },\n };\n\n writeJsonFile(GLOBAL_CONFIG_FILE, config);\n return config;\n}\n\nexport function isEnabled(): boolean {\n if (\n process.env[ENV_TELEMETRY_DISABLED] === \"1\" ||\n process.env[ENV_TELEMETRY_DISABLED]?.toLowerCase() === \"true\"\n ) {\n return false;\n }\n\n if (\n process.env[ENV_DO_NOT_TRACK] === \"1\" ||\n process.env[ENV_DO_NOT_TRACK]?.toLowerCase() === \"true\"\n ) {\n return false;\n }\n\n if (ci.isCI) {\n return true;\n }\n\n const config = getGlobalConfig();\n return config.telemetry.enabled;\n}\n\nexport function isDebugMode(): boolean {\n return (\n process.env[ENV_TELEMETRY_DEBUG] === \"1\" ||\n process.env[ENV_TELEMETRY_DEBUG]?.toLowerCase() === \"true\"\n );\n}\n\nexport function setEnabled(enabled: boolean): void {\n const config = getGlobalConfig();\n config.telemetry.enabled = enabled;\n writeJsonFile(GLOBAL_CONFIG_FILE, config);\n}\n\nexport function getMachineId(): string {\n if (ci.isCI) {\n return ci.name ?? \"unknown-ci\";\n }\n\n return getGlobalConfig().machineId;\n}\n\nconst hook: Hook<\"finally\"> = async ({\n id: command,\n config: { version },\n error,\n}) => {\n if (!isEnabled()) {\n return;\n }\n\n const event: TelemetryEvent = {\n version,\n machineId: getMachineId(),\n sessionId: crypto.randomUUID(),\n isCI: ci.isCI,\n nodeVersion: process.version,\n platform: process.platform,\n outcome: error ? \"failure\" : \"success\",\n error: error?.message,\n };\n\n if (isDebugMode()) {\n console.error(\n \"[Telemetry Debug] Would send event:\",\n JSON.stringify(event, null, 2),\n );\n return;\n }\n\n try {\n const client = getPostHogClient();\n client.capture({\n distinctId: event.machineId,\n event: command,\n properties: event,\n });\n } catch {\n // Silently ignore telemetry errors - never block CLI operation\n }\n};\n\nexport default hook;\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type SpawnFn, TunnelManager } from "./tunnel.js";
|
|
2
|
+
export type TunnelControlServer = {
|
|
3
|
+
port: number;
|
|
4
|
+
manager: TunnelManager;
|
|
5
|
+
close: () => Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export declare function startTunnelControlServer(getPort: () => number, options?: {
|
|
8
|
+
spawn?: SpawnFn;
|
|
9
|
+
}): Promise<TunnelControlServer>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import { TunnelManager } from "./tunnel.js";
|
|
3
|
+
import { createTunnelHandler } from "./tunnel-handler.js";
|
|
4
|
+
export async function startTunnelControlServer(getPort, options) {
|
|
5
|
+
const manager = new TunnelManager({ getPort, spawn: options?.spawn });
|
|
6
|
+
const server = http.createServer(createTunnelHandler(manager));
|
|
7
|
+
await new Promise((resolve, reject) => {
|
|
8
|
+
server.once("error", reject);
|
|
9
|
+
server.listen(0, "127.0.0.1", () => {
|
|
10
|
+
server.off("error", reject);
|
|
11
|
+
resolve();
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
const address = server.address();
|
|
15
|
+
if (typeof address === "string" || address === null) {
|
|
16
|
+
server.close();
|
|
17
|
+
throw new Error("tunnel control server has no address");
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
port: address.port,
|
|
21
|
+
manager,
|
|
22
|
+
close: () => new Promise((resolve, reject) => {
|
|
23
|
+
manager.stop();
|
|
24
|
+
// Force any in-flight SSE connections to drop so server.close()
|
|
25
|
+
// doesn't hang indefinitely on subscribers that never end on their own.
|
|
26
|
+
server.closeAllConnections();
|
|
27
|
+
server.close((err) => (err ? reject(err) : resolve()));
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=tunnel-control-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-control-server.js","sourceRoot":"","sources":["../../src/cli/tunnel-control-server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAgB,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAQ1D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAqB,EACrB,OAA6B;IAE7B,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO;QACP,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpC,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,gEAAgE;YAChE,wEAAwE;YACxE,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC;KACL,CAAC;AACJ,CAAC","sourcesContent":["import http from \"node:http\";\nimport { type SpawnFn, TunnelManager } from \"./tunnel.js\";\nimport { createTunnelHandler } from \"./tunnel-handler.js\";\n\nexport type TunnelControlServer = {\n port: number;\n manager: TunnelManager;\n close: () => Promise<void>;\n};\n\nexport async function startTunnelControlServer(\n getPort: () => number,\n options?: { spawn?: SpawnFn },\n): Promise<TunnelControlServer> {\n const manager = new TunnelManager({ getPort, spawn: options?.spawn });\n const server = http.createServer(createTunnelHandler(manager));\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n if (typeof address === \"string\" || address === null) {\n server.close();\n throw new Error(\"tunnel control server has no address\");\n }\n return {\n port: address.port,\n manager,\n close: () =>\n new Promise<void>((resolve, reject) => {\n manager.stop();\n // Force any in-flight SSE connections to drop so server.close()\n // doesn't hang indefinitely on subscribers that never end on their own.\n server.closeAllConnections();\n server.close((err) => (err ? reject(err) : resolve()));\n }),\n };\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { startTunnelControlServer } from "./tunnel-control-server.js";
|
|
3
|
+
let openControl;
|
|
4
|
+
afterEach(async () => {
|
|
5
|
+
await openControl?.close();
|
|
6
|
+
openControl = undefined;
|
|
7
|
+
});
|
|
8
|
+
describe("startTunnelControlServer", () => {
|
|
9
|
+
it("listens on a random loopback port and serves /__skybridge/tunnel/events", async () => {
|
|
10
|
+
const control = await startTunnelControlServer(() => 3000);
|
|
11
|
+
openControl = control;
|
|
12
|
+
expect(control.port).toBeGreaterThan(0);
|
|
13
|
+
const res = await fetch(`http://127.0.0.1:${control.port}/__skybridge/tunnel/events`);
|
|
14
|
+
expect(res.headers.get("content-type")).toMatch(/text\/event-stream/);
|
|
15
|
+
const reader = res.body.getReader();
|
|
16
|
+
const { value } = await reader.read();
|
|
17
|
+
const chunk = new TextDecoder().decode(value);
|
|
18
|
+
expect(chunk).toContain("event: state");
|
|
19
|
+
expect(chunk).toContain('"status":"idle"');
|
|
20
|
+
await reader.cancel();
|
|
21
|
+
});
|
|
22
|
+
it("two concurrent control servers get different ports", async () => {
|
|
23
|
+
const a = await startTunnelControlServer(() => 3000);
|
|
24
|
+
const b = await startTunnelControlServer(() => 4000);
|
|
25
|
+
try {
|
|
26
|
+
expect(a.port).not.toBe(b.port);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
await a.close();
|
|
30
|
+
await b.close();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
it("close() shuts the listener", async () => {
|
|
34
|
+
const control = await startTunnelControlServer(() => 3000);
|
|
35
|
+
await control.close();
|
|
36
|
+
await expect(fetch(`http://127.0.0.1:${control.port}/__skybridge/tunnel/events`)).rejects.toThrow();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=tunnel-control-server.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-control-server.test.js","sourceRoot":"","sources":["../../src/cli/tunnel-control-server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,IAAI,WAAuD,CAAC;AAC5D,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,WAAW,EAAE,KAAK,EAAE,CAAC;IAC3B,WAAW,GAAG,SAAS,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3D,WAAW,GAAG,OAAO,CAAC;QAEtB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,oBAAoB,OAAO,CAAC,IAAI,4BAA4B,CAC7D,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAEtE,MAAM,MAAM,GAAI,GAAG,CAAC,IAAmC,CAAC,SAAS,EAAE,CAAC;QACpE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC3C,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,CAAC,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,CACV,KAAK,CAAC,oBAAoB,OAAO,CAAC,IAAI,4BAA4B,CAAC,CACpE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { afterEach, describe, expect, it } from \"vitest\";\nimport { startTunnelControlServer } from \"./tunnel-control-server.js\";\n\nlet openControl: { close: () => Promise<void> } | undefined;\nafterEach(async () => {\n await openControl?.close();\n openControl = undefined;\n});\n\ndescribe(\"startTunnelControlServer\", () => {\n it(\"listens on a random loopback port and serves /__skybridge/tunnel/events\", async () => {\n const control = await startTunnelControlServer(() => 3000);\n openControl = control;\n\n expect(control.port).toBeGreaterThan(0);\n\n const res = await fetch(\n `http://127.0.0.1:${control.port}/__skybridge/tunnel/events`,\n );\n expect(res.headers.get(\"content-type\")).toMatch(/text\\/event-stream/);\n\n const reader = (res.body as ReadableStream<Uint8Array>).getReader();\n const { value } = await reader.read();\n const chunk = new TextDecoder().decode(value);\n expect(chunk).toContain(\"event: state\");\n expect(chunk).toContain('\"status\":\"idle\"');\n await reader.cancel();\n });\n\n it(\"two concurrent control servers get different ports\", async () => {\n const a = await startTunnelControlServer(() => 3000);\n const b = await startTunnelControlServer(() => 4000);\n try {\n expect(a.port).not.toBe(b.port);\n } finally {\n await a.close();\n await b.close();\n }\n });\n\n it(\"close() shuts the listener\", async () => {\n const control = await startTunnelControlServer(() => 3000);\n await control.close();\n await expect(\n fetch(`http://127.0.0.1:${control.port}/__skybridge/tunnel/events`),\n ).rejects.toThrow();\n });\n});\n"]}
|