veryfront 0.1.128 → 0.1.129
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/esm/cli/router.d.ts +0 -5
- package/esm/cli/router.d.ts.map +1 -1
- package/esm/cli/router.js +30 -2
- package/esm/cli/shared/update-check.d.ts +4 -0
- package/esm/cli/shared/update-check.d.ts.map +1 -0
- package/esm/cli/shared/update-check.js +97 -0
- package/esm/deno.d.ts +5 -0
- package/esm/deno.js +13 -8
- package/esm/src/channels/control-plane.d.ts.map +1 -1
- package/esm/src/channels/control-plane.js +5 -5
- package/esm/src/channels/invoke.d.ts +1 -1
- package/esm/src/channels/invoke.d.ts.map +1 -1
- package/esm/src/channels/invoke.js +6 -6
- package/esm/src/chat/index.d.ts +12 -24
- package/esm/src/chat/index.d.ts.map +1 -1
- package/esm/src/chat/index.js +5 -25
- package/esm/src/config/env.d.ts.map +1 -1
- package/esm/src/config/env.js +18 -10
- package/esm/src/data/static-data-fetcher.d.ts +3 -0
- package/esm/src/data/static-data-fetcher.d.ts.map +1 -1
- package/esm/src/data/static-data-fetcher.js +29 -25
- package/esm/src/data/static-paths-fetcher.d.ts.map +1 -1
- package/esm/src/data/static-paths-fetcher.js +3 -2
- package/esm/src/errors/logging.d.ts.map +1 -1
- package/esm/src/errors/logging.js +16 -7
- package/esm/src/errors/user-friendly/error-formatter.d.ts.map +1 -1
- package/esm/src/errors/user-friendly/error-formatter.js +9 -25
- package/esm/src/fs/index.d.ts +11 -12
- package/esm/src/fs/index.d.ts.map +1 -1
- package/esm/src/fs/index.js +11 -24
- package/esm/src/html/dev-scripts.d.ts.map +1 -1
- package/esm/src/html/dev-scripts.js +5 -8
- package/esm/src/html/html-escape.d.ts +1 -0
- package/esm/src/html/html-escape.d.ts.map +1 -1
- package/esm/src/html/html-escape.js +3 -0
- package/esm/src/html/html-injection.js +2 -2
- package/esm/src/html/html-shell-generator.d.ts +5 -2
- package/esm/src/html/html-shell-generator.d.ts.map +1 -1
- package/esm/src/html/html-shell-generator.js +41 -30
- package/esm/src/html/hydration-script-builder/dev-client-renderer.js +2 -2
- package/esm/src/html/hydration-script-builder/dev-component-manifest.js +2 -2
- package/esm/src/html/hydration-script-builder/dev-error-logger.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/dev-error-logger.js +2 -6
- package/esm/src/html/hydration-script-builder/dev-scripts.js +2 -2
- package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts +3 -1
- package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/hydration-data-generator.js +2 -2
- package/esm/src/html/hydration-script-builder/index.d.ts +1 -1
- package/esm/src/html/hydration-script-builder/index.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/index.js +1 -1
- package/esm/src/html/hydration-script-builder/prod-hydration.js +2 -2
- package/esm/src/html/hydration-script-builder/prod-scripts.d.ts +2 -0
- package/esm/src/html/hydration-script-builder/prod-scripts.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/prod-scripts.js +14 -14
- package/esm/src/html/schemas/html.schema.d.ts +2 -0
- package/esm/src/html/schemas/html.schema.d.ts.map +1 -1
- package/esm/src/html/schemas/html.schema.js +2 -0
- package/esm/src/html/styles-builder/css-pregeneration.d.ts +17 -1
- package/esm/src/html/styles-builder/css-pregeneration.d.ts.map +1 -1
- package/esm/src/html/styles-builder/css-pregeneration.js +103 -1
- package/esm/src/html/styles-builder/dev-styles.js +2 -2
- package/esm/src/html/utils.d.ts +2 -0
- package/esm/src/html/utils.d.ts.map +1 -1
- package/esm/src/html/utils.js +49 -28
- package/esm/src/integrations/remote-tools.d.ts.map +1 -1
- package/esm/src/integrations/remote-tools.js +32 -39
- package/esm/src/internal-agents/ag-ui-sse.d.ts +0 -1
- package/esm/src/internal-agents/ag-ui-sse.d.ts.map +1 -1
- package/esm/src/internal-agents/ag-ui-sse.js +2 -16
- package/esm/src/internal-agents/control-plane-auth.d.ts.map +1 -1
- package/esm/src/internal-agents/control-plane-auth.js +5 -3
- package/esm/src/internal-agents/request-body.d.ts.map +1 -1
- package/esm/src/internal-agents/request-body.js +6 -3
- package/esm/src/internal-agents/session-manager.d.ts +1 -0
- package/esm/src/internal-agents/session-manager.d.ts.map +1 -1
- package/esm/src/internal-agents/session-manager.js +12 -18
- package/esm/src/issues/core.d.ts.map +1 -1
- package/esm/src/issues/core.js +24 -23
- package/esm/src/issues/schemas/issue.schema.d.ts.map +1 -1
- package/esm/src/issues/schemas/issue.schema.js +2 -1
- package/esm/src/jobs/runtime-env.d.ts.map +1 -1
- package/esm/src/jobs/runtime-env.js +21 -44
- package/esm/src/markdown/index.d.ts +1 -2
- package/esm/src/markdown/index.d.ts.map +1 -1
- package/esm/src/markdown/index.js +1 -6
- package/esm/src/mcp/server.d.ts +0 -1
- package/esm/src/mcp/server.d.ts.map +1 -1
- package/esm/src/mcp/server.js +40 -41
- package/esm/src/mdx/index.d.ts +3 -2
- package/esm/src/mdx/index.d.ts.map +1 -1
- package/esm/src/mdx/index.js +3 -5
- package/esm/src/middleware/builtin/logger.d.ts.map +1 -1
- package/esm/src/middleware/builtin/logger.js +31 -28
- package/esm/src/middleware/builtin/security/rate-limit.d.ts.map +1 -1
- package/esm/src/middleware/builtin/security/rate-limit.js +17 -12
- package/esm/src/middleware/builtin/timeout.d.ts.map +1 -1
- package/esm/src/middleware/builtin/timeout.js +17 -10
- package/esm/src/modules/import-map/default-import-map.d.ts.map +1 -1
- package/esm/src/modules/import-map/default-import-map.js +4 -3
- package/esm/src/oauth/handlers/callback-handler.d.ts +0 -5
- package/esm/src/oauth/handlers/callback-handler.d.ts.map +1 -1
- package/esm/src/oauth/handlers/callback-handler.js +9 -14
- package/esm/src/oauth/handlers/index.d.ts +1 -1
- package/esm/src/oauth/handlers/index.js +1 -1
- package/esm/src/oauth/handlers/init-handler.d.ts.map +1 -1
- package/esm/src/oauth/handlers/init-handler.js +32 -20
- package/esm/src/oauth/providers/index.d.ts +1 -1
- package/esm/src/oauth/providers/index.js +1 -1
- package/esm/src/oauth/schemas/index.d.ts +1 -1
- package/esm/src/oauth/schemas/index.js +1 -1
- package/esm/src/oauth/token-store/index.d.ts +1 -1
- package/esm/src/oauth/token-store/index.js +1 -1
- package/esm/src/oauth/token-store/memory.d.ts +1 -1
- package/esm/src/oauth/token-store/memory.d.ts.map +1 -1
- package/esm/src/oauth/token-store/memory.js +8 -8
- package/esm/src/observability/request-profiler.d.ts +31 -0
- package/esm/src/observability/request-profiler.d.ts.map +1 -0
- package/esm/src/observability/request-profiler.js +94 -0
- package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
- package/esm/src/observability/tracing/otlp-setup.js +16 -21
- package/esm/src/prompt/factory.d.ts.map +1 -1
- package/esm/src/prompt/factory.js +10 -12
- package/esm/src/prompt/registry.d.ts.map +1 -1
- package/esm/src/prompt/registry.js +12 -10
- package/esm/src/prompt/schemas/prompt.schema.d.ts.map +1 -1
- package/esm/src/prompt/schemas/prompt.schema.js +0 -2
- package/esm/src/prompt/types.d.ts +1 -1
- package/esm/src/prompt/types.d.ts.map +1 -1
- package/esm/src/provider/local/ai-sdk-adapter.d.ts.map +1 -1
- package/esm/src/provider/local/ai-sdk-adapter.js +3 -8
- package/esm/src/provider/local/env.d.ts +4 -6
- package/esm/src/provider/local/env.d.ts.map +1 -1
- package/esm/src/provider/local/env.js +14 -1
- package/esm/src/provider/local/local-engine.d.ts.map +1 -1
- package/esm/src/provider/local/local-engine.js +2 -7
- package/esm/src/provider/model-registry.d.ts.map +1 -1
- package/esm/src/provider/model-registry.js +2 -7
- package/esm/src/provider/veryfront-cloud/provider.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/provider.js +1 -7
- package/esm/src/provider/veryfront-cloud/shared.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/shared.js +9 -11
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +56 -57
- package/esm/src/react/compat/hooks-adapter.d.ts +1 -7
- package/esm/src/react/compat/hooks-adapter.d.ts.map +1 -1
- package/esm/src/react/compat/hooks-adapter.js +35 -40
- package/esm/src/react/components/Head.d.ts +1 -26
- package/esm/src/react/components/Head.d.ts.map +1 -1
- package/esm/src/react/components/Head.js +1 -172
- package/esm/src/react/context/index.d.ts +2 -46
- package/esm/src/react/context/index.d.ts.map +1 -1
- package/esm/src/react/context/index.js +1 -44
- package/esm/src/react/head-collector.d.ts +1 -10
- package/esm/src/react/head-collector.d.ts.map +1 -1
- package/esm/src/react/head-collector.js +4 -0
- package/esm/src/react/router/index.d.ts +2 -45
- package/esm/src/react/router/index.d.ts.map +1 -1
- package/esm/src/react/router/index.js +1 -49
- package/esm/src/react/runtime/core.d.ts +49 -0
- package/esm/src/react/runtime/core.d.ts.map +1 -0
- package/esm/src/react/runtime/core.js +200 -0
- package/esm/src/rendering/orchestrator/html.d.ts +2 -0
- package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/html.js +69 -12
- package/esm/src/rendering/orchestrator/ssr-orchestrator.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/ssr-orchestrator.js +4 -0
- package/esm/src/rendering/orchestrator/types.d.ts +4 -0
- package/esm/src/rendering/orchestrator/types.d.ts.map +1 -1
- package/esm/src/repositories/types.d.ts.map +1 -1
- package/esm/src/resource/factory.d.ts.map +1 -1
- package/esm/src/resource/factory.js +12 -9
- package/esm/src/resource/registry.d.ts +3 -3
- package/esm/src/resource/registry.d.ts.map +1 -1
- package/esm/src/resource/registry.js +7 -7
- package/esm/src/schemas/common.d.ts.map +1 -1
- package/esm/src/schemas/common.js +7 -4
- package/esm/src/security/http/config.d.ts +0 -1
- package/esm/src/security/http/config.d.ts.map +1 -1
- package/esm/src/security/http/config.js +3 -16
- package/esm/src/security/http/response/security-handler.d.ts +1 -0
- package/esm/src/security/http/response/security-handler.d.ts.map +1 -1
- package/esm/src/security/http/response/security-handler.js +17 -12
- package/esm/src/security/index.d.ts +4 -2
- package/esm/src/security/index.d.ts.map +1 -1
- package/esm/src/security/index.js +3 -1
- package/esm/src/server/handlers/dev/styles-css.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/styles-css.handler.js +8 -7
- package/esm/src/server/handlers/monitoring/metrics.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/monitoring/metrics.handler.js +3 -1
- package/esm/src/server/handlers/request/module/module-server-handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/module/module-server-handler.js +18 -15
- package/esm/src/server/handlers/request/prod-hydration-module.handler.d.ts +8 -0
- package/esm/src/server/handlers/request/prod-hydration-module.handler.d.ts.map +1 -0
- package/esm/src/server/handlers/request/prod-hydration-module.handler.js +41 -0
- package/esm/src/server/handlers/request/ssr/ssr.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/ssr/ssr.handler.js +3 -0
- package/esm/src/server/production-server.d.ts.map +1 -1
- package/esm/src/server/production-server.js +65 -0
- package/esm/src/server/runtime-handler/handler-context-builder.d.ts +1 -1
- package/esm/src/server/runtime-handler/handler-context-builder.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.d.ts +1 -1
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +36 -11
- package/esm/src/server/runtime-handler/request-utils.d.ts +7 -0
- package/esm/src/server/runtime-handler/request-utils.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/request-utils.js +10 -0
- package/esm/src/server/services/rendering/ssr.service.d.ts +1 -0
- package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
- package/esm/src/server/services/rendering/ssr.service.js +12 -5
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +1 -1
- package/esm/src/skill/allowed-tools.d.ts +3 -8
- package/esm/src/skill/allowed-tools.d.ts.map +1 -1
- package/esm/src/skill/executor.js +2 -2
- package/esm/src/skill/parser.d.ts.map +1 -1
- package/esm/src/skill/parser.js +12 -12
- package/esm/src/skill/path-safety.js +1 -1
- package/esm/src/skill/tools.d.ts.map +1 -1
- package/esm/src/skill/tools.js +18 -11
- package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
- package/esm/src/studio/bridge/bridge-bundle.generated.js +1 -1
- package/esm/src/task/discovery.d.ts.map +1 -1
- package/esm/src/task/discovery.js +73 -95
- package/esm/src/tool/executor.d.ts.map +1 -1
- package/esm/src/tool/executor.js +8 -7
- package/esm/src/tool/factory.d.ts.map +1 -1
- package/esm/src/tool/factory.js +13 -16
- package/esm/src/transforms/esm/package-registry.d.ts +4 -0
- package/esm/src/transforms/esm/package-registry.d.ts.map +1 -1
- package/esm/src/transforms/esm/package-registry.js +34 -17
- package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.d.ts.map +1 -1
- package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.js +2 -1
- package/esm/src/transforms/mdx/esm-module-loader/cache-format.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/cache-format.js +26 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.js +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts +1 -0
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.js +3 -0
- package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.d.ts +1 -1
- package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.js +1 -1
- package/esm/src/transforms/veryfront-module-urls.d.ts.map +1 -1
- package/esm/src/transforms/veryfront-module-urls.js +7 -3
- package/esm/src/types/entities/getEntityInfo.d.ts.map +1 -1
- package/esm/src/types/entities/getEntityInfo.js +79 -127
- package/esm/src/utils/path-utils.d.ts +1 -1
- package/esm/src/utils/path-utils.d.ts.map +1 -1
- package/esm/src/utils/path-utils.js +16 -7
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/esm/src/utils/version.d.ts.map +1 -1
- package/esm/src/utils/version.js +0 -1
- package/esm/src/workflow/worker/dynamic-job-entrypoint.d.ts.map +1 -1
- package/esm/src/workflow/worker/dynamic-job-entrypoint.js +5 -72
- package/esm/src/workflow/worker/job-entrypoint.d.ts.map +1 -1
- package/esm/src/workflow/worker/job-entrypoint.js +5 -72
- package/esm/src/workflow/worker/shared.d.ts +18 -0
- package/esm/src/workflow/worker/shared.d.ts.map +1 -0
- package/esm/src/workflow/worker/shared.js +77 -0
- package/package.json +1 -1
- package/src/cli/router.ts +41 -2
- package/src/cli/shared/update-check.ts +110 -0
- package/src/deno.js +13 -8
- package/src/src/channels/control-plane.ts +6 -10
- package/src/src/channels/invoke.ts +7 -7
- package/src/src/chat/index.ts +96 -132
- package/src/src/config/env.ts +24 -11
- package/src/src/data/static-data-fetcher.ts +59 -34
- package/src/src/data/static-paths-fetcher.ts +4 -2
- package/src/src/errors/logging.ts +21 -7
- package/src/src/errors/user-friendly/error-formatter.ts +14 -29
- package/src/src/fs/index.ts +21 -30
- package/src/src/html/dev-scripts.ts +5 -9
- package/src/src/html/html-escape.ts +4 -0
- package/src/src/html/html-injection.ts +2 -2
- package/src/src/html/html-shell-generator.ts +60 -26
- package/src/src/html/hydration-script-builder/dev-client-renderer.ts +2 -2
- package/src/src/html/hydration-script-builder/dev-component-manifest.ts +2 -2
- package/src/src/html/hydration-script-builder/dev-error-logger.ts +2 -8
- package/src/src/html/hydration-script-builder/dev-scripts.ts +2 -2
- package/src/src/html/hydration-script-builder/hydration-data-generator.ts +2 -1
- package/src/src/html/hydration-script-builder/index.ts +5 -1
- package/src/src/html/hydration-script-builder/prod-hydration.ts +2 -2
- package/src/src/html/hydration-script-builder/prod-scripts.ts +16 -15
- package/src/src/html/schemas/html.schema.ts +2 -0
- package/src/src/html/styles-builder/css-pregeneration.ts +133 -1
- package/src/src/html/styles-builder/dev-styles.ts +2 -2
- package/src/src/html/utils.ts +62 -29
- package/src/src/integrations/remote-tools.ts +39 -37
- package/src/src/internal-agents/ag-ui-sse.ts +2 -17
- package/src/src/internal-agents/control-plane-auth.ts +8 -6
- package/src/src/internal-agents/request-body.ts +7 -5
- package/src/src/internal-agents/session-manager.ts +16 -20
- package/src/src/issues/core.ts +24 -27
- package/src/src/issues/schemas/issue.schema.ts +3 -1
- package/src/src/jobs/runtime-env.ts +24 -50
- package/src/src/markdown/index.ts +5 -8
- package/src/src/mcp/server.ts +50 -53
- package/src/src/mdx/index.ts +7 -8
- package/src/src/middleware/builtin/logger.ts +44 -29
- package/src/src/middleware/builtin/security/rate-limit.ts +20 -11
- package/src/src/middleware/builtin/timeout.ts +22 -13
- package/src/src/modules/import-map/default-import-map.ts +4 -3
- package/src/src/oauth/handlers/callback-handler.ts +9 -16
- package/src/src/oauth/handlers/index.ts +1 -1
- package/src/src/oauth/handlers/init-handler.ts +56 -27
- package/src/src/oauth/providers/index.ts +1 -1
- package/src/src/oauth/schemas/index.ts +1 -1
- package/src/src/oauth/token-store/index.ts +1 -1
- package/src/src/oauth/token-store/memory.ts +8 -8
- package/src/src/observability/request-profiler.ts +140 -0
- package/src/src/observability/tracing/otlp-setup.ts +16 -22
- package/src/src/prompt/factory.ts +16 -14
- package/src/src/prompt/registry.ts +14 -13
- package/src/src/prompt/schemas/prompt.schema.ts +0 -4
- package/src/src/prompt/types.ts +1 -2
- package/src/src/provider/local/ai-sdk-adapter.ts +3 -10
- package/src/src/provider/local/env.ts +22 -2
- package/src/src/provider/local/local-engine.ts +2 -9
- package/src/src/provider/model-registry.ts +2 -9
- package/src/src/provider/veryfront-cloud/provider.ts +1 -8
- package/src/src/provider/veryfront-cloud/shared.ts +12 -15
- package/src/src/proxy/handler.ts +90 -74
- package/src/src/react/compat/hooks-adapter.ts +43 -44
- package/src/src/react/components/Head.tsx +1 -181
- package/src/src/react/context/index.tsx +2 -83
- package/src/src/react/head-collector.ts +9 -0
- package/src/src/react/router/index.tsx +2 -100
- package/src/src/react/runtime/core.ts +303 -0
- package/src/src/rendering/orchestrator/html.ts +122 -18
- package/src/src/rendering/orchestrator/ssr-orchestrator.ts +8 -0
- package/src/src/rendering/orchestrator/types.ts +4 -0
- package/src/src/repositories/types.ts +0 -4
- package/src/src/resource/factory.ts +15 -11
- package/src/src/resource/registry.ts +7 -7
- package/src/src/schemas/common.ts +8 -5
- package/src/src/security/http/config.ts +3 -19
- package/src/src/security/http/response/security-handler.ts +22 -13
- package/src/src/security/index.ts +4 -7
- package/src/src/server/handlers/dev/styles-css.handler.ts +32 -14
- package/src/src/server/handlers/monitoring/metrics.handler.ts +3 -1
- package/src/src/server/handlers/request/module/module-server-handler.ts +24 -17
- package/src/src/server/handlers/request/prod-hydration-module.handler.ts +61 -0
- package/src/src/server/handlers/request/ssr/ssr.handler.ts +3 -0
- package/src/src/server/production-server.ts +84 -0
- package/src/src/server/runtime-handler/handler-context-builder.ts +1 -1
- package/src/src/server/runtime-handler/index.ts +44 -13
- package/src/src/server/runtime-handler/request-utils.ts +11 -0
- package/src/src/server/services/rendering/ssr.service.ts +31 -18
- package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +1 -1
- package/src/src/skill/allowed-tools.ts +1 -8
- package/src/src/skill/executor.ts +2 -2
- package/src/src/skill/parser.ts +13 -20
- package/src/src/skill/path-safety.ts +1 -1
- package/src/src/skill/tools.ts +27 -20
- package/src/src/studio/bridge/bridge-bundle.generated.ts +1 -1
- package/src/src/task/discovery.ts +97 -97
- package/src/src/tool/executor.ts +10 -8
- package/src/src/tool/factory.ts +21 -22
- package/src/src/tool/types.ts +0 -17
- package/src/src/transforms/esm/package-registry.ts +52 -20
- package/src/src/transforms/import-rewriter/strategies/veryfront-strategy.ts +2 -1
- package/src/src/transforms/mdx/esm-module-loader/cache-format.ts +34 -1
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/index.ts +1 -1
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.ts +4 -0
- package/src/src/transforms/pipeline/stages/ssr-vf-modules/index.ts +1 -1
- package/src/src/transforms/veryfront-module-urls.ts +6 -2
- package/src/src/types/entities/getEntityInfo.ts +131 -152
- package/src/src/utils/path-utils.ts +16 -7
- package/src/src/utils/version-constant.ts +1 -1
- package/src/src/utils/version.ts +0 -1
- package/src/src/workflow/worker/dynamic-job-entrypoint.ts +18 -84
- package/src/src/workflow/worker/job-entrypoint.ts +18 -85
- package/src/src/workflow/worker/shared.ts +127 -0
- package/esm/src/prompt/schemas/index.d.ts +0 -7
- package/esm/src/prompt/schemas/index.d.ts.map +0 -1
- package/esm/src/prompt/schemas/index.js +0 -6
- package/esm/src/security/http/handlers-index.d.ts +0 -5
- package/esm/src/security/http/handlers-index.d.ts.map +0 -1
- package/esm/src/security/http/handlers-index.js +0 -3
- package/src/src/prompt/schemas/index.ts +0 -7
- package/src/src/security/http/handlers-index.ts +0 -4
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
export const STUDIO_BRIDGE_BUNDLE: string = "// src/studio/bridge/bridge-logger.ts\nfunction normalizeContext(context) {\n if (!context) return void 0;\n if (context instanceof Error) {\n return { error: context.message, ...context.stack ? { stack: context.stack } : {} };\n }\n return context;\n}\nfunction formatArgs(message, context) {\n const normalized = normalizeContext(context);\n if (!normalized || Object.keys(normalized).length === 0) {\n return [message];\n }\n return [message, normalized];\n}\nvar logger = {\n debug(message, context) {\n console.debug(...formatArgs(message, context));\n },\n info(message, context) {\n console.log(...formatArgs(message, context));\n },\n warn(message, context) {\n console.warn(...formatArgs(message, context));\n },\n error(message, context) {\n console.error(...formatArgs(message, context));\n }\n};\n\n// src/studio/bridge/bridge-config.ts\nvar config = null;\nfunction initConfig() {\n const raw = globalThis.__VF_BRIDGE_CONFIG__;\n const params = new URLSearchParams(window.location.search);\n const qsMode = params.get(\"vf_studio_mode\");\n const resolveMode = (value) => value === \"simple\" || qsMode === \"simple\" ? \"simple\" : \"advanced\";\n if (!raw || typeof raw !== \"object\") {\n logger.warn(\"No bridge config found on window.__VF_BRIDGE_CONFIG__\");\n config = {\n projectId: \"\",\n pageId: \"\",\n pagePath: \"\",\n wsUrl: \"\",\n yjsGuid: \"\",\n studioMode: resolveMode(void 0),\n debugSkipInit: false,\n debugExposeInternals: false\n };\n return;\n }\n config = {\n projectId: String(raw.projectId ?? \"\"),\n pageId: String(raw.pageId ?? \"\"),\n pagePath: String(raw.pagePath ?? raw.pageId ?? \"\"),\n wsUrl: String(raw.wsUrl ?? \"\"),\n yjsGuid: String(raw.yjsGuid ?? \"\"),\n studioMode: resolveMode(raw.studioMode),\n debugSkipInit: !!raw.debugSkipInit,\n debugExposeInternals: !!raw.debugExposeInternals\n };\n}\nfunction getConfig() {\n if (!config) {\n throw new Error(\"[StudioBridge] Config not initialized. Call initConfig() first.\");\n }\n return config;\n}\n\n// src/studio/bridge/bridge-state.ts\nvar state = {\n // Inspector\n inspectMode: false,\n selectedNodeId: null,\n hoveredNodeId: null,\n lastTreeSignature: \"\",\n // Overlays\n hoverOverlay: null,\n selectionOverlay: null,\n // Console\n originalConsole: {},\n logCounter: 0,\n // Screenshot\n html2canvasLoaded: false,\n html2canvasPromise: null\n};\nvar CONSOLE_METHODS = [\n \"log\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"table\",\n \"clear\",\n \"dir\"\n];\nvar DOM_IGNORE_TAGS = [\"SCRIPT\", \"STYLE\", \"LINK\", \"META\", \"NOSCRIPT\"];\n\n// src/studio/bridge/bridge-messaging.ts\nvar studioOrigin = null;\nfunction postToStudio(message) {\n if (!window.parent || window.parent === window) return;\n try {\n window.parent.postMessage(message, studioOrigin || \"*\");\n } catch (e) {\n logger.debug(\"postMessage failed\", e instanceof Error ? e : { error: String(e) });\n }\n}\nfunction isFromStudio(event) {\n try {\n if (!event.source || event.source === window) return false;\n const url = new URL(event.origin || \"\");\n const host = url.hostname;\n const valid = host === \"localhost\" || host.endsWith(\".veryfront.org\") || host === \"veryfront.org\" || host.endsWith(\".veryfront.com\") || host === \"veryfront.com\" || host.endsWith(\".veryfront.dev\") || host === \"veryfront.dev\";\n if (valid && !studioOrigin) {\n studioOrigin = event.origin;\n }\n return valid;\n } catch (_) {\n return false;\n }\n}\n\n// src/studio/bridge/bridge-styles.ts\nvar OVERLAY_CSS = `\n /* ------------------------------------------------------------------ */\n /* Overlays (hover / selection inspector) */\n /* ------------------------------------------------------------------ */\n\n .vf-overlay {\n position: fixed;\n pointer-events: none;\n z-index: 99999;\n box-sizing: border-box;\n transition: all 0.05s ease-out;\n }\n .vf-overlay-hover {\n border: 2px solid oklch(0.6852 0.162 241.8);\n background: oklch(0.6852 0.162 241.8 / 0.06);\n }\n .vf-overlay-selection {\n border: 2px solid oklch(0.6852 0.162 241.8);\n background: oklch(0.6852 0.162 241.8 / 0.1);\n }\n .vf-overlay-label {\n position: absolute;\n top: -22px;\n left: -2px;\n background: oklch(0.6852 0.162 241.8);\n color: white;\n font-size: 11px;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n padding: 2px 6px;\n border-radius: 3px 3px 0 0;\n white-space: nowrap;\n pointer-events: none;\n }\n .vf-overlay-label-bottom {\n top: auto;\n bottom: -22px;\n border-radius: 0 0 3px 3px;\n }\n\n /* ------------------------------------------------------------------ */\n /* Edit button (floating CTA) */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-edit-button {\n position: fixed;\n right: 16px;\n bottom: 16px;\n z-index: 100001;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 9999px;\n background: oklch(0.2768 0 0);\n color: oklch(0.9512 0.008 98.88);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 13px;\n font-weight: 500;\n line-height: 1;\n padding: 10px 16px;\n cursor: pointer;\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n transition: transform 100ms ease, box-shadow 100ms ease;\n }\n .vf-markdown-edit-button:hover {\n box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);\n }\n .vf-markdown-edit-button:active {\n transform: scale(0.98);\n }\n\n /* ------------------------------------------------------------------ */\n /* Editor root */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor {\n position: fixed;\n inset: 0;\n z-index: 100000;\n background: oklch(1 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n display: none;\n }\n\n .vf-markdown-editor__history {\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 13px;\n line-height: 1;\n min-width: 28px;\n height: 28px;\n padding: 0 8px;\n cursor: pointer;\n transition: background 75ms ease;\n }\n .vf-markdown-editor__history:hover {\n background: oklch(0.93 0 0);\n }\n\n /* ------------------------------------------------------------------ */\n /* Surface (editor area) */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__surface-wrap {\n position: relative;\n height: 100vh;\n }\n\n .vf-markdown-editor__surface {\n width: 100%;\n max-width: 980px;\n margin: 0 auto;\n height: 100%;\n overflow: auto;\n outline: none;\n position: relative;\n z-index: 1;\n background: transparent;\n padding: 32px 40px;\n box-sizing: border-box;\n }\n\n /* ------------------------------------------------------------------ */\n /* Selection overlay */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__selection-overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 2;\n display: none;\n }\n\n .vf-markdown-editor__selection-highlight {\n position: absolute;\n border-radius: 3px;\n opacity: 0.26;\n }\n\n .vf-markdown-editor__selection-caret {\n position: absolute;\n width: 2px;\n border-radius: 1px;\n }\n\n .vf-markdown-editor__selection-label {\n position: absolute;\n transform: translateY(-100%);\n margin-top: -4px;\n border-radius: 9999px;\n padding: 1px 7px;\n font-size: 10px;\n line-height: 1.4;\n white-space: nowrap;\n color: oklch(1 0 0);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.16);\n }\n\n /* ------------------------------------------------------------------ */\n /* Slash menu */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__slash-menu {\n position: fixed;\n z-index: 100005;\n min-width: 240px;\n max-width: 300px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 8px;\n background: oklch(1 0 0);\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n padding: 4px;\n display: none;\n }\n\n .vf-markdown-editor__slash-section {\n padding: 8px 10px 4px;\n font-size: 11px;\n font-weight: 600;\n color: oklch(0.55 0.005 95.11);\n text-transform: none;\n letter-spacing: 0;\n }\n\n .vf-markdown-editor__slash-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n border: 0;\n border-radius: 6px;\n background: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n text-align: left;\n padding: 6px 10px;\n cursor: pointer;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__slash-item:hover,\n .vf-markdown-editor__slash-item[data-active='true'] {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__slash-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 4px;\n background: oklch(1 0 0);\n font-size: 13px;\n font-weight: 600;\n color: oklch(0.2768 0 0);\n flex-shrink: 0;\n }\n\n .vf-markdown-editor__slash-item-title {\n display: block;\n font-size: 13px;\n font-weight: 500;\n color: oklch(0.2768 0 0);\n line-height: 1.35;\n flex: 1;\n }\n\n .vf-markdown-editor__slash-item-desc {\n display: none;\n }\n\n .vf-markdown-editor__slash-shortcut {\n font-size: 11px;\n color: oklch(0.55 0.005 95.11);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n flex-shrink: 0;\n }\n\n .vf-markdown-editor__slash-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 10px;\n margin-top: 2px;\n border-top: 1px solid oklch(0.9 0 0);\n font-size: 11px;\n color: oklch(0.55 0.005 95.11);\n }\n\n .vf-markdown-editor__slash-footer-key {\n font-size: 10px;\n color: oklch(0.55 0.005 95.11);\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 3px;\n padding: 1px 4px;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n }\n\n /* ------------------------------------------------------------------ */\n /* Inline toolbar */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__inline-toolbar {\n position: fixed;\n z-index: 100006;\n display: none;\n flex-direction: column;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 8px;\n background: oklch(1 0 0);\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n padding: 4px;\n }\n\n .vf-markdown-editor__inline-row {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 2px 0;\n }\n\n .vf-markdown-editor__inline-separator {\n width: 1px;\n height: 20px;\n background: oklch(0.9 0 0);\n margin: 0 2px;\n flex-shrink: 0;\n }\n\n .vf-markdown-editor__inline-button {\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n min-width: 26px;\n height: 26px;\n padding: 0 7px;\n cursor: pointer;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__inline-button:hover {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__inline-button.active {\n background: oklch(0.6852 0.162 241.8 / 0.14);\n color: oklch(0.6852 0.162 241.8);\n }\n\n .vf-markdown-editor__inline-button[data-format='bold'] {\n font-weight: 700;\n }\n\n .vf-markdown-editor__inline-button[data-format='italic'] {\n font-style: italic;\n }\n\n .vf-markdown-editor__inline-button[data-format='strikethrough'] {\n text-decoration: line-through;\n }\n\n /* ------------------------------------------------------------------ */\n /* Block type trigger */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-trigger {\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n height: 26px;\n padding: 0 7px;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 2px;\n white-space: nowrap;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__block-trigger:hover {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__block-trigger::after {\n content: '\\\\25BE';\n font-size: 10px;\n color: oklch(0.55 0.005 95.11);\n }\n\n /* ------------------------------------------------------------------ */\n /* Block dropdown */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-dropdown {\n position: absolute;\n top: 100%;\n left: 4px;\n z-index: 100007;\n min-width: 160px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n padding: 4px;\n margin-top: 4px;\n display: none;\n }\n\n .vf-markdown-editor__block-option {\n display: block;\n width: 100%;\n border: 0;\n border-radius: 6px;\n background: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n text-align: left;\n padding: 6px 10px;\n font-size: 13px;\n font-weight: 500;\n color: oklch(0.2768 0 0);\n cursor: pointer;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__block-option:hover {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__block-option.active {\n background: oklch(0.6852 0.162 241.8 / 0.1);\n color: oklch(0.6852 0.162 241.8);\n }\n\n /* ------------------------------------------------------------------ */\n /* Block drag handle */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-handle {\n position: fixed;\n z-index: 100007;\n display: none;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n color: oklch(0.2768 0 0);\n font-size: 12px;\n font-weight: 700;\n line-height: 1;\n width: 28px;\n height: 28px;\n padding: 0;\n cursor: grab;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px -1px rgba(0,0,0,0.1);\n transition: background 75ms ease, box-shadow 75ms ease;\n }\n\n .vf-markdown-editor__block-handle:hover {\n background: oklch(0.6852 0.162 241.8 / 0.1);\n }\n\n .vf-markdown-editor__block-handle[data-dragging='true'] {\n cursor: grabbing;\n }\n\n /* ------------------------------------------------------------------ */\n /* Block drop indicator */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-drop-indicator {\n position: fixed;\n z-index: 100006;\n display: none;\n height: 2px;\n border-radius: 9999px;\n background: oklch(0.6852 0.162 241.8);\n box-shadow: 0 1px 6px oklch(0.6852 0.162 241.8 / 0.5);\n }\n\n .vf-markdown-editor__block-drop-label {\n position: fixed;\n z-index: 100007;\n display: none;\n border-radius: 9999px;\n border: 1px solid oklch(0.6852 0.162 241.8 / 0.24);\n background: oklch(1 0 0 / 0.96);\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n font-weight: 600;\n line-height: 1.2;\n padding: 3px 8px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px -1px rgba(0,0,0,0.1);\n }\n\n /* ------------------------------------------------------------------ */\n /* Block drag ghost */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-drag-ghost {\n position: fixed;\n top: -9999px;\n left: -9999px;\n width: 260px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 8px;\n background: oklch(1 0 0);\n box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);\n padding: 8px 10px;\n }\n\n .vf-markdown-editor__block-drag-ghost-title {\n display: block;\n font-size: 11px;\n font-weight: 700;\n color: oklch(0.2768 0 0);\n }\n\n .vf-markdown-editor__block-drag-ghost-text {\n display: block;\n margin-top: 4px;\n font-size: 11px;\n color: oklch(0.55 0.005 95.11);\n line-height: 1.35;\n }\n\n /* ------------------------------------------------------------------ */\n /* MDX blocks bar */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__mdx-blocks {\n display: none;\n gap: 8px;\n padding: 8px 16px;\n border-bottom: 1px solid oklch(0.9 0 0);\n background: oklch(0.97 0 0 / 0.95);\n overflow-x: auto;\n }\n\n .vf-markdown-editor__mdx-block {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n padding: 6px 8px;\n }\n\n .vf-markdown-editor__mdx-block-label {\n font-size: 11px;\n color: oklch(0.2768 0 0);\n white-space: nowrap;\n }\n\n .vf-markdown-editor__mdx-note {\n font-size: 10px;\n color: oklch(0.55 0.005 95.11);\n white-space: nowrap;\n }\n\n .vf-markdown-editor__mdx-open {\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n line-height: 1;\n padding: 5px 7px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 75ms ease;\n }\n .vf-markdown-editor__mdx-open:hover {\n background: oklch(0.93 0 0);\n }\n\n /* ------------------------------------------------------------------ */\n /* Lexical surface overrides */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__surface [data-lexical-editor] {\n outline: none;\n }\n\n .vf-markdown-editor__surface s,\n .vf-markdown-editor__surface del,\n .vf-markdown-editor__surface [style*='line-through'] {\n text-decoration: line-through;\n }\n\n .vf-markdown-editor__surface p:empty::before {\n content: \"Type '/' for commands\";\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n font-style: normal;\n }\n\n .vf-markdown-editor__surface h1:empty::before {\n content: 'Heading 1';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface h2:empty::before {\n content: 'Heading 2';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface h3:empty::before {\n content: 'Heading 3';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface blockquote:empty::before {\n content: 'Quote';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface p {\n min-height: 1.5em;\n }\n\n /* ------------------------------------------------------------------ */\n /* Textarea fallback */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__textarea {\n width: 100%;\n height: 100vh;\n border: 0;\n outline: none;\n resize: none;\n display: none;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;\n font-size: 14px;\n line-height: 1.6;\n color: oklch(0.2768 0 0);\n background: transparent;\n padding: 16px;\n box-sizing: border-box;\n }\n\n /* ================================================================== */\n /* DARK MODE */\n /* ================================================================== */\n\n [data-theme='dark'] .vf-markdown-editor {\n background: oklch(0.2768 0 0);\n }\n\n [data-theme='dark'] .vf-markdown-editor__history {\n background: oklch(0.3211 0 0);\n border-color: oklch(0.42 0.0017 106.48);\n color: oklch(0.9512 0.008 98.88);\n }\n [data-theme='dark'] .vf-markdown-editor__history:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__textarea {\n color: oklch(0.9512 0.008 98.88);\n }\n\n /* Slash menu \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__slash-menu {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.21 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-section {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-item:hover,\n [data-theme='dark'] .vf-markdown-editor__slash-item[data-active='true'] {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-icon {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-item-title {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-shortcut {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-footer {\n border-top-color: oklch(0.3 0.01 220);\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-footer-key {\n border-color: oklch(0.42 0.0017 106.48);\n color: oklch(0.5338 0.0046 106.55);\n }\n\n /* Inline toolbar \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__inline-toolbar {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.21 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-separator {\n background: oklch(0.3 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-button {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-button:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-button.active {\n background: oklch(0.6852 0.162 241.8 / 0.2);\n color: oklch(0.75 0.14 241.8);\n }\n\n /* Block trigger \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__block-trigger {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-trigger:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-trigger::after {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n /* Block dropdown \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__block-dropdown {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.21 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-option {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-option:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-option.active {\n background: oklch(0.6852 0.162 241.8 / 0.2);\n color: oklch(0.75 0.14 241.8);\n }\n\n /* Placeholder text \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__surface p:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface h1:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface h2:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface h3:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface blockquote:empty::before {\n color: oklch(0.5338 0.0046 106.55 / 0.5);\n }\n\n /* Block drag \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__block-handle {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-handle:hover {\n background: oklch(0.6852 0.162 241.8 / 0.2);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drop-label {\n border-color: oklch(0.6852 0.162 241.8 / 0.35);\n background: oklch(0.18 0.01 220 / 0.96);\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drag-ghost {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drag-ghost-title {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drag-ghost-text {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n /* MDX blocks \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__mdx-blocks {\n border-bottom-color: oklch(0.3 0.01 220);\n background: oklch(0.18 0.01 220 / 0.8);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-block {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-block-label {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-note {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-open {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.2768 0 0);\n color: oklch(0.9512 0.008 98.88);\n }\n [data-theme='dark'] .vf-markdown-editor__mdx-open:hover {\n background: oklch(0.25 0.01 220);\n }\n\n /* Edit button \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-edit-button {\n background: oklch(0.9512 0.008 98.88);\n color: oklch(0.2768 0 0);\n border-color: oklch(0.42 0.0017 106.48);\n }\n`;\nfunction injectOverlayStyles() {\n if (document.getElementById(\"vf-overlay-styles\")) return;\n const style = document.createElement(\"style\");\n style.id = \"vf-overlay-styles\";\n style.textContent = OVERLAY_CSS;\n try {\n document.head.appendChild(style);\n if (!style.sheet) {\n logger.warn(\"Inline style injection may be blocked by CSP (style-src)\");\n }\n } catch (error) {\n logger.warn(\n \"Failed to inject bridge styles. This may be caused by CSP style-src restrictions.\",\n error instanceof Error ? error : {\n error: String(error)\n }\n );\n }\n}\n\n// src/studio/bridge/bridge-constants.ts\nvar DATA_VF_ID = \"data-vf-id\";\nvar DATA_VF_SELECTOR = \"data-vf-selector\";\nvar DATA_VF_TEXT = \"data-vf-text\";\nvar DATA_VF_IGNORE = \"data-vf-ignore\";\nvar DATA_NODE_ID = \"data-node-id\";\nvar DATA_NODE_FILE = \"data-node-file\";\nvar DATA_NODE_NAME = \"data-node-name\";\nvar DATA_NODE_LINE = \"data-node-line\";\nvar DATA_NODE_COLUMN = \"data-node-column\";\nvar DATA_NODE_SOURCE = \"data-node-source\";\n\n// src/studio/bridge/bridge-utils.ts\nfunction debounce(fn, ms) {\n let timer;\n const debounced = function(...args) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n fn.apply(this, args);\n }, ms);\n };\n debounced.cancel = () => {\n clearTimeout(timer);\n timer = void 0;\n };\n return debounced;\n}\n\n// src/studio/bridge/bridge-inspector.ts\nfunction createOverlay(type) {\n const overlay = document.createElement(\"div\");\n overlay.className = \"vf-overlay vf-overlay-\" + type;\n overlay.setAttribute(DATA_VF_IGNORE, \"true\");\n const label = document.createElement(\"div\");\n label.className = \"vf-overlay-label\";\n overlay.appendChild(label);\n overlay.style.display = \"none\";\n document.body.appendChild(overlay);\n return overlay;\n}\nfunction hideOverlay(overlay) {\n if (overlay) overlay.style.display = \"none\";\n}\nfunction positionOverlay(overlay, element, nodeName) {\n if (!overlay) return;\n if (!element) {\n hideOverlay(overlay);\n return;\n }\n const rect = element.getBoundingClientRect();\n overlay.style.display = \"block\";\n overlay.style.top = rect.top + \"px\";\n overlay.style.left = rect.left + \"px\";\n overlay.style.width = rect.width + \"px\";\n overlay.style.height = rect.height + \"px\";\n const label = overlay.querySelector(\".vf-overlay-label\");\n if (label) {\n label.textContent = nodeName;\n if (rect.top < 24) {\n label.classList.add(\"vf-overlay-label-bottom\");\n } else {\n label.classList.remove(\"vf-overlay-label-bottom\");\n }\n }\n}\nfunction getNodeName(element) {\n const vfId = element.getAttribute(DATA_VF_ID);\n if (vfId) return vfId.split(\"_\")[0] ?? vfId;\n return element.tagName.toLowerCase();\n}\nfunction findElementById(nodeId) {\n if (!nodeId) return null;\n return document.querySelector(\"[\" + DATA_VF_ID + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_VF_SELECTOR + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_NODE_ID + '=\"' + nodeId + '\"]');\n}\nfunction isValidElement(el) {\n return !!el && el.nodeType === Node.ELEMENT_NODE && !DOM_IGNORE_TAGS.includes(el.tagName) && !el.hasAttribute(DATA_VF_IGNORE) && el.style.display !== \"none\";\n}\nfunction getNodeType(el) {\n const vfId = el.getAttribute(DATA_VF_ID) || \"\";\n if (vfId && /^[A-Z]/.test(vfId)) return \"component\";\n if (el.hasAttribute(DATA_VF_TEXT)) return \"text\";\n if (el.getAttribute(DATA_NODE_SOURCE) === \"md\") return \"markdown\";\n return \"element\";\n}\nfunction buildNavigatorTree(root) {\n const config3 = getConfig();\n let nodeIndex = 0;\n function processElement(el, parentId) {\n if (!isValidElement(el)) {\n const children = [];\n Array.from(el.children || []).forEach((child) => {\n children.push(...processElement(child, parentId));\n });\n return children;\n }\n let id = el.getAttribute(DATA_VF_ID) || el.getAttribute(DATA_NODE_ID) || el.getAttribute(DATA_VF_SELECTOR);\n if (!id) {\n id = \"vf-\" + el.tagName.toLowerCase() + \"-\" + ++nodeIndex;\n el.setAttribute(DATA_VF_SELECTOR, id);\n }\n const vfId = el.getAttribute(DATA_VF_ID);\n const name = vfId ? vfId.split(\"_\")[0] ?? vfId : el.tagName.toLowerCase();\n const node = {\n id,\n name,\n type: getNodeType(el),\n path: config3.pagePath,\n parentId,\n start: {\n line: parseInt(el.getAttribute(DATA_NODE_LINE) || \"0\", 10),\n column: parseInt(el.getAttribute(DATA_NODE_COLUMN) || \"0\", 10)\n },\n end: { line: 0, column: 0 },\n children: [],\n text: el.hasAttribute(DATA_VF_TEXT) ? el.textContent?.trim() : void 0,\n isRemote: false\n };\n Array.from(el.children || []).forEach((child) => {\n node.children.push(...processElement(child, id));\n });\n return [node];\n }\n const rootNode = {\n id: \"root\",\n name: \"root\",\n type: \"root\",\n path: \"\",\n parentId: \"\",\n start: { line: 0, column: 0 },\n end: { line: 0, column: 0 },\n children: [],\n isRemote: false\n };\n Array.from(root.children || []).forEach((child) => {\n rootNode.children.push(...processElement(child, \"root\"));\n });\n return rootNode;\n}\nfunction createTreeSignature(root) {\n const validElements = Array.from(root.querySelectorAll(\"*\")).filter((el) => isValidElement(el));\n return validElements.length + \"-\" + validElements.map((el) => el.tagName).join(\"\");\n}\nvar treeUpdateTimer = null;\nvar mutationObserver = null;\nfunction sendTreeUpdate() {\n const config3 = getConfig();\n const root = document.getElementById(\"root\") || document.body;\n if (!root) return;\n const signature = createTreeSignature(root);\n if (signature === state.lastTreeSignature) return;\n state.lastTreeSignature = signature;\n postToStudio({\n action: \"treeUpdated\",\n id: config3.pageId,\n url: window.location.href,\n tree: buildNavigatorTree(root),\n sourceHash: globalThis.__VERYFRONT_SOURCE_HASH__ || null\n });\n}\nfunction debouncedTreeUpdate() {\n if (treeUpdateTimer) clearTimeout(treeUpdateTimer);\n treeUpdateTimer = setTimeout(sendTreeUpdate, 150);\n}\nfunction setupMutationObserver() {\n const root = document.getElementById(\"root\") || document.body;\n if (!root) return;\n mutationObserver = new MutationObserver(function(mutations) {\n const hasRelevantChanges = mutations.some(\n (m) => m.type === \"childList\" || m.type === \"characterData\"\n );\n if (!hasRelevantChanges) return;\n if (state.selectedNodeId && !findElementById(state.selectedNodeId)) {\n state.selectedNodeId = null;\n hideOverlay(state.selectionOverlay);\n postToStudio({ action: \"setSelectedNode\", id: null });\n }\n debouncedTreeUpdate();\n });\n mutationObserver.observe(root, { childList: true, characterData: true, subtree: true });\n sendTreeUpdate();\n}\nfunction showOverlay(overlay, nodeId) {\n if (!nodeId) {\n hideOverlay(overlay);\n return;\n }\n const el = findElementById(nodeId);\n if (!el) {\n hideOverlay(overlay);\n return;\n }\n positionOverlay(overlay, el, getNodeName(el));\n}\nfunction showHoverOverlay(nodeId) {\n showOverlay(state.hoverOverlay, nodeId);\n}\nfunction showSelectionOverlay(nodeId) {\n showOverlay(state.selectionOverlay, nodeId);\n}\nfunction scrollToElement(nodeId) {\n const el = document.querySelector(\"[\" + DATA_VF_ID + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_NODE_ID + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_VF_SELECTOR + '*=\"' + nodeId + '\"]');\n if (el) el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n}\nfunction getDirectText(el) {\n let text = \"\";\n for (let i = 0; i < el.childNodes.length; i++) {\n const node = el.childNodes[i];\n if (node?.nodeType === Node.TEXT_NODE) {\n text += node.textContent || \"\";\n }\n }\n return text.trim();\n}\nfunction setupInspectMode() {\n const INSPECTABLE_SELECTOR = \"[\" + DATA_VF_ID + \"], [\" + DATA_VF_SELECTOR + \"], [\" + DATA_NODE_ID + \"], [\" + DATA_NODE_FILE + \"]\";\n function getElementId(el) {\n return el.getAttribute(DATA_VF_ID) || el.getAttribute(DATA_NODE_ID) || el.getAttribute(DATA_VF_SELECTOR);\n }\n document.addEventListener(\n \"click\",\n function(event) {\n if (!state.inspectMode) return;\n event.preventDefault();\n event.stopPropagation();\n const target = event.target.closest(INSPECTABLE_SELECTOR);\n if (!target) {\n state.selectedNodeId = null;\n hideOverlay(state.selectionOverlay);\n postToStudio({ action: \"setSelectedNode\", id: null });\n return;\n }\n const id = getElementId(target);\n state.selectedNodeId = id;\n showSelectionOverlay(id);\n postToStudio({\n action: \"setSelectedNode\",\n id,\n node: {\n name: target.getAttribute(DATA_NODE_NAME) || target.tagName.toLowerCase(),\n type: getNodeType(target),\n file: target.getAttribute(DATA_NODE_FILE) || getConfig().pagePath,\n line: parseInt(target.getAttribute(DATA_NODE_LINE) || \"0\", 10),\n column: parseInt(target.getAttribute(DATA_NODE_COLUMN) || \"0\", 10),\n text: getDirectText(target).slice(0, 200)\n }\n });\n },\n true\n );\n document.addEventListener(\"pointerover\", function(event) {\n if (!state.inspectMode || event.pointerType === \"touch\") return;\n const target = event.target.closest(INSPECTABLE_SELECTOR);\n if (!target) return;\n const id = getElementId(target);\n if (id === state.hoveredNodeId) return;\n state.hoveredNodeId = id;\n showHoverOverlay(id);\n });\n document.addEventListener(\"pointerout\", function(event) {\n if (!state.inspectMode || event.pointerType === \"touch\") return;\n const target = event.target.closest(INSPECTABLE_SELECTOR);\n if (!target) return;\n const relatedTarget = event.relatedTarget;\n if (relatedTarget && target.contains(relatedTarget)) return;\n state.hoveredNodeId = null;\n hideOverlay(state.hoverOverlay);\n });\n const updateOverlays = debounce(function() {\n if (state.inspectMode && state.hoveredNodeId) showHoverOverlay(state.hoveredNodeId);\n if (state.selectedNodeId) showSelectionOverlay(state.selectedNodeId);\n }, 16);\n window.addEventListener(\"scroll\", updateOverlays, true);\n window.addEventListener(\"resize\", updateOverlays);\n}\nfunction setColorMode(mode) {\n document.documentElement.setAttribute(\"data-theme\", mode);\n document.documentElement.classList.remove(\"light\", \"dark\");\n document.documentElement.classList.add(mode);\n}\n\n// src/studio/bridge/bridge-console.ts\nfunction setupConsoleCapture() {\n const consoleObj = console;\n CONSOLE_METHODS.forEach((method) => {\n state.originalConsole[method] = consoleObj[method];\n consoleObj[method] = function(...args) {\n state.originalConsole[method].apply(console, args);\n const logId = \"vf-\" + Date.now() + \"-\" + ++state.logCounter;\n const formattedData = args.map((arg) => {\n try {\n if (arg instanceof Error) {\n return { __isError: true, message: arg.message, stack: arg.stack, name: arg.name };\n }\n if (arg === void 0) return { __isUndefined: true };\n if (arg === null) return null;\n if (typeof arg === \"function\") {\n return { __isFunction: true, name: arg.name || \"anonymous\" };\n }\n if (typeof arg === \"symbol\") return { __isSymbol: true, description: arg.description };\n if (typeof arg === \"object\") return JSON.parse(JSON.stringify(arg));\n return arg;\n } catch (_) {\n return String(arg);\n }\n });\n postToStudio({\n action: \"logEvent\",\n value: {\n id: logId,\n method,\n data: formattedData,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n }\n });\n };\n });\n}\nfunction setupErrorHandling() {\n function hideOverlays() {\n hideOverlay(state.hoverOverlay);\n hideOverlay(state.selectionOverlay);\n }\n window.addEventListener(\"error\", function(event) {\n hideOverlays();\n postToStudio({\n action: \"runtimeError\",\n url: window.location.href,\n errors: [\n {\n type: \"error\",\n message: event.message,\n file: event.filename,\n line: event.lineno,\n column: event.colno\n }\n ]\n });\n });\n window.addEventListener(\"unhandledrejection\", function(event) {\n hideOverlays();\n const reason = event.reason;\n postToStudio({\n action: \"runtimeError\",\n url: window.location.href,\n errors: [\n {\n type: \"error\",\n message: reason instanceof Error ? reason.message : String(reason),\n file: reason instanceof Error ? reason.stack : void 0\n }\n ]\n });\n });\n}\n\n// src/studio/bridge/bridge-screenshot.ts\nfunction loadHtml2Canvas() {\n if (state.html2canvasLoaded) return Promise.resolve();\n if (state.html2canvasPromise) return state.html2canvasPromise;\n state.html2canvasPromise = new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://cdn.jsdelivr.net/npm/html2canvas-pro@2.0.0/dist/html2canvas-pro.min.js\";\n script.onload = () => {\n state.html2canvasLoaded = true;\n resolve();\n };\n script.onerror = (event) => {\n logger.warn(\n \"Failed to load html2canvas script. This may be caused by CSP script-src restrictions.\",\n { event: String(event) }\n );\n reject(new Error(\"Failed to load html2canvas script\"));\n };\n try {\n document.head.appendChild(script);\n } catch (error) {\n logger.warn(\n \"Failed to append html2canvas script element. This may be caused by CSP script-src restrictions.\",\n error instanceof Error ? error : { error: String(error) }\n );\n reject(\n error instanceof Error ? error : new Error(\"Failed to append html2canvas script element\")\n );\n }\n });\n return state.html2canvasPromise;\n}\nasync function captureScreenshot(options) {\n const { scrollTo, fullPage, quality = 0.8 } = options || {};\n const originalScrollY = window.scrollY;\n try {\n await loadHtml2Canvas();\n if (typeof scrollTo === \"number\") {\n window.scrollTo(0, scrollTo);\n await new Promise((r) => setTimeout(r, 150));\n }\n const canvasOptions = {\n useCORS: true,\n logging: false,\n scale: window.devicePixelRatio || 1\n };\n if (fullPage) {\n canvasOptions.height = document.documentElement.scrollHeight;\n canvasOptions.windowHeight = document.documentElement.scrollHeight;\n canvasOptions.y = 0;\n window.scrollTo(0, 0);\n await new Promise((r) => setTimeout(r, 100));\n }\n const html2canvasFn = window.html2canvas.default || window.html2canvas;\n const canvas = await html2canvasFn(document.body, canvasOptions);\n if (!canvas || canvas.width === 0 || canvas.height === 0) {\n logger.error(\"html2canvas produced empty canvas\", {\n width: canvas?.width,\n height: canvas?.height\n });\n window.scrollTo(0, originalScrollY);\n return {\n success: false,\n error: \"html2canvas produced empty canvas (0x0 dimensions)\"\n };\n }\n const dataUrl = canvas.toDataURL(\"image/png\", quality);\n if (!dataUrl || !dataUrl.startsWith(\"data:image/\") || dataUrl.length < 100) {\n logger.error(\"html2canvas produced invalid data URL\", {\n dataUrlPreview: dataUrl?.substring(0, 50)\n });\n window.scrollTo(0, originalScrollY);\n return {\n success: false,\n error: \"html2canvas produced invalid image data\"\n };\n }\n window.scrollTo(0, originalScrollY);\n return {\n success: true,\n data: dataUrl,\n width: canvas.width,\n height: canvas.height,\n scrollY: window.scrollY,\n totalHeight: document.documentElement.scrollHeight,\n viewportHeight: window.innerHeight,\n url: window.location.href\n };\n } catch (error) {\n logger.error(\"html2canvas error\", error instanceof Error ? error : { error: String(error) });\n window.scrollTo(0, originalScrollY);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n}\nasync function captureMultipleSections(sectionCount) {\n const originalScrollY = window.scrollY;\n const results = [];\n const totalHeight = document.documentElement.scrollHeight;\n const viewportHeight = window.innerHeight;\n const sections = sectionCount || Math.ceil(totalHeight / viewportHeight);\n try {\n for (let i = 0; i < sections; i++) {\n const scrollY = Math.min(i * viewportHeight, totalHeight - viewportHeight);\n const result = await captureScreenshot({ scrollTo: scrollY });\n if (result.success) {\n results.push({ ...result, section: i + 1, totalSections: sections });\n }\n }\n } finally {\n window.scrollTo(0, originalScrollY);\n }\n return results;\n}\n\n// src/studio/bridge/bridge-message-handler.ts\nvar SAFE_PROTOCOLS = /* @__PURE__ */ new Set([\"http:\", \"https:\"]);\nfunction isSafeNavigationUrl(url) {\n if (url.startsWith(\"/\")) return true;\n try {\n const parsed = new URL(url, window.location.origin);\n return SAFE_PROTOCOLS.has(parsed.protocol);\n } catch {\n return false;\n }\n}\nfunction handleStudioMessage(event) {\n if (!isFromStudio(event)) return;\n const message = event.data;\n if (!message?.action) return;\n const config3 = getConfig();\n switch (message.action) {\n case \"routeChange\":\n if (message.url) {\n if (!isSafeNavigationUrl(message.url)) {\n logger.warn(\"[StudioBridge] Blocked unsafe URL in routeChange\", { url: message.url });\n return;\n }\n if (state.selectedNodeId) {\n state.selectedNodeId = null;\n hideOverlay(state.selectionOverlay);\n postToStudio({ action: \"setSelectedNode\", id: null });\n }\n postToStudio({\n action: \"onPageTransitionStart\",\n url: message.url,\n projectId: config3.projectId\n });\n window.location.href = message.url;\n }\n return;\n case \"reload\":\n window.location.reload();\n return;\n case \"goBack\":\n window.history.back();\n return;\n case \"goForward\":\n window.history.forward();\n return;\n case \"colorMode\":\n setColorMode(message.value);\n return;\n case \"toggleInspectMode\":\n state.inspectMode = message.value;\n if (state.inspectMode) return;\n hideOverlay(state.hoverOverlay);\n state.hoveredNodeId = null;\n if (!message.deselectElements) return;\n hideOverlay(state.selectionOverlay);\n state.selectedNodeId = null;\n return;\n case \"setSelectedNode\":\n state.selectedNodeId = message.id;\n showSelectionOverlay(message.id);\n if (message.scroll) scrollToElement(message.id);\n return;\n case \"setHoveredNode\":\n if (!state.inspectMode) showHoverOverlay(message.id);\n return;\n case \"screenshot\":\n (async function() {\n if (message.multipleSections) {\n const results = await captureMultipleSections(message.sectionCount);\n postToStudio({\n action: \"screenshotResult\",\n requestId: message.requestId,\n multiple: true,\n results\n });\n return;\n }\n const result = await captureScreenshot(message.options);\n postToStudio({\n action: \"screenshotResult\",\n requestId: message.requestId,\n multiple: false,\n ...result\n });\n })();\n return;\n default:\n logger.debug(\"Unknown action\", { action: message.action });\n return;\n }\n}\n\n// src/studio/bridge/bridge-init.ts\nfunction notifyAppLoaded() {\n const config3 = getConfig();\n postToStudio({ action: \"appLoaded\", url: window.location.href });\n postToStudio({\n action: \"appUpdated\",\n url: window.location.href,\n id: config3.pageId,\n isInitialLoad: true,\n errors: [],\n warnings: []\n });\n postToStudio({\n action: \"onPageTransitionEnd\",\n url: window.location.href,\n projectId: config3.projectId,\n id: config3.pageId,\n params: {}\n });\n}\nfunction notifyAppUnloaded() {\n postToStudio({ action: \"appUnloaded\", url: window.location.href });\n}\nfunction init() {\n const config3 = getConfig();\n const params = new URLSearchParams(window.location.search);\n const studioEmbed = params.get(\"studio_embed\") === \"true\";\n const isStandalone = window.parent === window && !studioEmbed;\n if (isStandalone) {\n logger.debug(\n \"[StudioBridge] Not in iframe and not studio_embed mode, skipping initialization\"\n );\n return;\n }\n logger.debug(\"Initializing...\");\n if (!isStandalone) {\n injectOverlayStyles();\n state.hoverOverlay = createOverlay(\"hover\");\n state.selectionOverlay = createOverlay(\"selection\");\n setupConsoleCapture();\n setupErrorHandling();\n setupInspectMode();\n }\n window.addEventListener(\"message\", handleStudioMessage);\n if (!isStandalone) {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", function() {\n notifyAppLoaded();\n setupMutationObserver();\n }, { once: true });\n } else {\n notifyAppLoaded();\n setupMutationObserver();\n }\n window.addEventListener(\"beforeunload\", notifyAppUnloaded, { once: true });\n }\n const colorMode = params.get(\"color_mode\");\n if (colorMode) setColorMode(colorMode);\n if (!isStandalone) {\n const inspectModeParam = params.get(\"inspect_mode\");\n if (inspectModeParam === \"true\") {\n state.inspectMode = true;\n logger.debug(\"Inspect mode enabled from query param\");\n }\n }\n logger.debug(\"Initialized successfully\");\n}\n\n// src/studio/bridge/bridge-coordinator.ts\ninitConfig();\nvar config2 = getConfig();\nif (!config2.debugSkipInit) {\n init();\n}\n";
|
|
9
|
+
export const STUDIO_BRIDGE_BUNDLE: string = "// src/studio/bridge/bridge-logger.ts\nfunction normalizeContext(context) {\n if (!context) return void 0;\n if (context instanceof Error) {\n return { error: context.message, ...context.stack ? { stack: context.stack } : {} };\n }\n return context;\n}\nfunction formatArgs(message, context) {\n const normalized = normalizeContext(context);\n if (!normalized || Object.keys(normalized).length === 0) {\n return [message];\n }\n return [message, normalized];\n}\nvar logger = {\n debug(message, context) {\n console.debug(...formatArgs(message, context));\n },\n info(message, context) {\n console.log(...formatArgs(message, context));\n },\n warn(message, context) {\n console.warn(...formatArgs(message, context));\n },\n error(message, context) {\n console.error(...formatArgs(message, context));\n }\n};\n\n// src/studio/bridge/bridge-config.ts\nvar config = null;\nvar DEFAULT_CONFIG = {\n projectId: \"\",\n pageId: \"\",\n pagePath: \"\",\n wsUrl: \"\",\n yjsGuid: \"\",\n studioMode: \"advanced\",\n debugSkipInit: false,\n debugExposeInternals: false\n};\nfunction resolveStudioMode(value, queryString) {\n const params = new URLSearchParams(queryString);\n return value === \"simple\" || params.get(\"vf_studio_mode\") === \"simple\" ? \"simple\" : \"advanced\";\n}\nfunction normalizeConfig(raw) {\n const queryString = window.location.search;\n if (!raw || typeof raw !== \"object\") {\n logger.warn(\"No bridge config found on window.__VF_BRIDGE_CONFIG__\");\n return {\n ...DEFAULT_CONFIG,\n studioMode: resolveStudioMode(void 0, queryString)\n };\n }\n return {\n ...DEFAULT_CONFIG,\n projectId: String(raw.projectId ?? \"\"),\n pageId: String(raw.pageId ?? \"\"),\n pagePath: String(raw.pagePath ?? raw.pageId ?? \"\"),\n wsUrl: String(raw.wsUrl ?? \"\"),\n yjsGuid: String(raw.yjsGuid ?? \"\"),\n studioMode: resolveStudioMode(raw.studioMode, queryString),\n debugSkipInit: !!raw.debugSkipInit,\n debugExposeInternals: !!raw.debugExposeInternals\n };\n}\nfunction initConfig() {\n const raw = globalThis.__VF_BRIDGE_CONFIG__;\n config = normalizeConfig(raw);\n}\nfunction getConfig() {\n if (!config) {\n throw new Error(\"[StudioBridge] Config not initialized. Call initConfig() first.\");\n }\n return config;\n}\n\n// src/studio/bridge/bridge-state.ts\nvar state = {\n // Inspector\n inspectMode: false,\n selectedNodeId: null,\n hoveredNodeId: null,\n lastTreeSignature: \"\",\n // Overlays\n hoverOverlay: null,\n selectionOverlay: null,\n // Console\n originalConsole: {},\n logCounter: 0,\n // Screenshot\n html2canvasLoaded: false,\n html2canvasPromise: null\n};\nvar CONSOLE_METHODS = [\n \"log\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"table\",\n \"clear\",\n \"dir\"\n];\nvar DOM_IGNORE_TAGS = [\"SCRIPT\", \"STYLE\", \"LINK\", \"META\", \"NOSCRIPT\"];\n\n// src/studio/bridge/bridge-messaging.ts\nvar studioOrigin = null;\nfunction postToStudio(message) {\n if (!window.parent || window.parent === window) return;\n try {\n window.parent.postMessage(message, studioOrigin || \"*\");\n } catch (e) {\n logger.debug(\"postMessage failed\", e instanceof Error ? e : { error: String(e) });\n }\n}\nfunction isFromStudio(event) {\n try {\n if (!event.source || event.source === window) return false;\n const url = new URL(event.origin || \"\");\n const host = url.hostname;\n const valid = host === \"localhost\" || host.endsWith(\".veryfront.org\") || host === \"veryfront.org\" || host.endsWith(\".veryfront.com\") || host === \"veryfront.com\" || host.endsWith(\".veryfront.dev\") || host === \"veryfront.dev\";\n if (valid && !studioOrigin) {\n studioOrigin = event.origin;\n }\n return valid;\n } catch (_) {\n return false;\n }\n}\n\n// src/studio/bridge/bridge-styles.ts\nvar OVERLAY_CSS = `\n /* ------------------------------------------------------------------ */\n /* Overlays (hover / selection inspector) */\n /* ------------------------------------------------------------------ */\n\n .vf-overlay {\n position: fixed;\n pointer-events: none;\n z-index: 99999;\n box-sizing: border-box;\n transition: all 0.05s ease-out;\n }\n .vf-overlay-hover {\n border: 2px solid oklch(0.6852 0.162 241.8);\n background: oklch(0.6852 0.162 241.8 / 0.06);\n }\n .vf-overlay-selection {\n border: 2px solid oklch(0.6852 0.162 241.8);\n background: oklch(0.6852 0.162 241.8 / 0.1);\n }\n .vf-overlay-label {\n position: absolute;\n top: -22px;\n left: -2px;\n background: oklch(0.6852 0.162 241.8);\n color: white;\n font-size: 11px;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n padding: 2px 6px;\n border-radius: 3px 3px 0 0;\n white-space: nowrap;\n pointer-events: none;\n }\n .vf-overlay-label-bottom {\n top: auto;\n bottom: -22px;\n border-radius: 0 0 3px 3px;\n }\n\n /* ------------------------------------------------------------------ */\n /* Edit button (floating CTA) */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-edit-button {\n position: fixed;\n right: 16px;\n bottom: 16px;\n z-index: 100001;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 9999px;\n background: oklch(0.2768 0 0);\n color: oklch(0.9512 0.008 98.88);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 13px;\n font-weight: 500;\n line-height: 1;\n padding: 10px 16px;\n cursor: pointer;\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n transition: transform 100ms ease, box-shadow 100ms ease;\n }\n .vf-markdown-edit-button:hover {\n box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);\n }\n .vf-markdown-edit-button:active {\n transform: scale(0.98);\n }\n\n /* ------------------------------------------------------------------ */\n /* Editor root */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor {\n position: fixed;\n inset: 0;\n z-index: 100000;\n background: oklch(1 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n display: none;\n }\n\n .vf-markdown-editor__history {\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 13px;\n line-height: 1;\n min-width: 28px;\n height: 28px;\n padding: 0 8px;\n cursor: pointer;\n transition: background 75ms ease;\n }\n .vf-markdown-editor__history:hover {\n background: oklch(0.93 0 0);\n }\n\n /* ------------------------------------------------------------------ */\n /* Surface (editor area) */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__surface-wrap {\n position: relative;\n height: 100vh;\n }\n\n .vf-markdown-editor__surface {\n width: 100%;\n max-width: 980px;\n margin: 0 auto;\n height: 100%;\n overflow: auto;\n outline: none;\n position: relative;\n z-index: 1;\n background: transparent;\n padding: 32px 40px;\n box-sizing: border-box;\n }\n\n /* ------------------------------------------------------------------ */\n /* Selection overlay */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__selection-overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 2;\n display: none;\n }\n\n .vf-markdown-editor__selection-highlight {\n position: absolute;\n border-radius: 3px;\n opacity: 0.26;\n }\n\n .vf-markdown-editor__selection-caret {\n position: absolute;\n width: 2px;\n border-radius: 1px;\n }\n\n .vf-markdown-editor__selection-label {\n position: absolute;\n transform: translateY(-100%);\n margin-top: -4px;\n border-radius: 9999px;\n padding: 1px 7px;\n font-size: 10px;\n line-height: 1.4;\n white-space: nowrap;\n color: oklch(1 0 0);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.16);\n }\n\n /* ------------------------------------------------------------------ */\n /* Slash menu */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__slash-menu {\n position: fixed;\n z-index: 100005;\n min-width: 240px;\n max-width: 300px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 8px;\n background: oklch(1 0 0);\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n padding: 4px;\n display: none;\n }\n\n .vf-markdown-editor__slash-section {\n padding: 8px 10px 4px;\n font-size: 11px;\n font-weight: 600;\n color: oklch(0.55 0.005 95.11);\n text-transform: none;\n letter-spacing: 0;\n }\n\n .vf-markdown-editor__slash-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n border: 0;\n border-radius: 6px;\n background: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n text-align: left;\n padding: 6px 10px;\n cursor: pointer;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__slash-item:hover,\n .vf-markdown-editor__slash-item[data-active='true'] {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__slash-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 4px;\n background: oklch(1 0 0);\n font-size: 13px;\n font-weight: 600;\n color: oklch(0.2768 0 0);\n flex-shrink: 0;\n }\n\n .vf-markdown-editor__slash-item-title {\n display: block;\n font-size: 13px;\n font-weight: 500;\n color: oklch(0.2768 0 0);\n line-height: 1.35;\n flex: 1;\n }\n\n .vf-markdown-editor__slash-item-desc {\n display: none;\n }\n\n .vf-markdown-editor__slash-shortcut {\n font-size: 11px;\n color: oklch(0.55 0.005 95.11);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n flex-shrink: 0;\n }\n\n .vf-markdown-editor__slash-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 10px;\n margin-top: 2px;\n border-top: 1px solid oklch(0.9 0 0);\n font-size: 11px;\n color: oklch(0.55 0.005 95.11);\n }\n\n .vf-markdown-editor__slash-footer-key {\n font-size: 10px;\n color: oklch(0.55 0.005 95.11);\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 3px;\n padding: 1px 4px;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n }\n\n /* ------------------------------------------------------------------ */\n /* Inline toolbar */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__inline-toolbar {\n position: fixed;\n z-index: 100006;\n display: none;\n flex-direction: column;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 8px;\n background: oklch(1 0 0);\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n padding: 4px;\n }\n\n .vf-markdown-editor__inline-row {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 2px 0;\n }\n\n .vf-markdown-editor__inline-separator {\n width: 1px;\n height: 20px;\n background: oklch(0.9 0 0);\n margin: 0 2px;\n flex-shrink: 0;\n }\n\n .vf-markdown-editor__inline-button {\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n min-width: 26px;\n height: 26px;\n padding: 0 7px;\n cursor: pointer;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__inline-button:hover {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__inline-button.active {\n background: oklch(0.6852 0.162 241.8 / 0.14);\n color: oklch(0.6852 0.162 241.8);\n }\n\n .vf-markdown-editor__inline-button[data-format='bold'] {\n font-weight: 700;\n }\n\n .vf-markdown-editor__inline-button[data-format='italic'] {\n font-style: italic;\n }\n\n .vf-markdown-editor__inline-button[data-format='strikethrough'] {\n text-decoration: line-through;\n }\n\n /* ------------------------------------------------------------------ */\n /* Block type trigger */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-trigger {\n border: 0;\n border-radius: 6px;\n background: transparent;\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n height: 26px;\n padding: 0 7px;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 2px;\n white-space: nowrap;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__block-trigger:hover {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__block-trigger::after {\n content: '\\\\25BE';\n font-size: 10px;\n color: oklch(0.55 0.005 95.11);\n }\n\n /* ------------------------------------------------------------------ */\n /* Block dropdown */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-dropdown {\n position: absolute;\n top: 100%;\n left: 4px;\n z-index: 100007;\n min-width: 160px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);\n padding: 4px;\n margin-top: 4px;\n display: none;\n }\n\n .vf-markdown-editor__block-option {\n display: block;\n width: 100%;\n border: 0;\n border-radius: 6px;\n background: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n text-align: left;\n padding: 6px 10px;\n font-size: 13px;\n font-weight: 500;\n color: oklch(0.2768 0 0);\n cursor: pointer;\n transition: background 75ms ease;\n }\n\n .vf-markdown-editor__block-option:hover {\n background: oklch(0.93 0 0);\n }\n\n .vf-markdown-editor__block-option.active {\n background: oklch(0.6852 0.162 241.8 / 0.1);\n color: oklch(0.6852 0.162 241.8);\n }\n\n /* ------------------------------------------------------------------ */\n /* Block drag handle */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-handle {\n position: fixed;\n z-index: 100007;\n display: none;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n color: oklch(0.2768 0 0);\n font-size: 12px;\n font-weight: 700;\n line-height: 1;\n width: 28px;\n height: 28px;\n padding: 0;\n cursor: grab;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px -1px rgba(0,0,0,0.1);\n transition: background 75ms ease, box-shadow 75ms ease;\n }\n\n .vf-markdown-editor__block-handle:hover {\n background: oklch(0.6852 0.162 241.8 / 0.1);\n }\n\n .vf-markdown-editor__block-handle[data-dragging='true'] {\n cursor: grabbing;\n }\n\n /* ------------------------------------------------------------------ */\n /* Block drop indicator */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-drop-indicator {\n position: fixed;\n z-index: 100006;\n display: none;\n height: 2px;\n border-radius: 9999px;\n background: oklch(0.6852 0.162 241.8);\n box-shadow: 0 1px 6px oklch(0.6852 0.162 241.8 / 0.5);\n }\n\n .vf-markdown-editor__block-drop-label {\n position: fixed;\n z-index: 100007;\n display: none;\n border-radius: 9999px;\n border: 1px solid oklch(0.6852 0.162 241.8 / 0.24);\n background: oklch(1 0 0 / 0.96);\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n font-weight: 600;\n line-height: 1.2;\n padding: 3px 8px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px -1px rgba(0,0,0,0.1);\n }\n\n /* ------------------------------------------------------------------ */\n /* Block drag ghost */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__block-drag-ghost {\n position: fixed;\n top: -9999px;\n left: -9999px;\n width: 260px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 8px;\n background: oklch(1 0 0);\n box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);\n padding: 8px 10px;\n }\n\n .vf-markdown-editor__block-drag-ghost-title {\n display: block;\n font-size: 11px;\n font-weight: 700;\n color: oklch(0.2768 0 0);\n }\n\n .vf-markdown-editor__block-drag-ghost-text {\n display: block;\n margin-top: 4px;\n font-size: 11px;\n color: oklch(0.55 0.005 95.11);\n line-height: 1.35;\n }\n\n /* ------------------------------------------------------------------ */\n /* MDX blocks bar */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__mdx-blocks {\n display: none;\n gap: 8px;\n padding: 8px 16px;\n border-bottom: 1px solid oklch(0.9 0 0);\n background: oklch(0.97 0 0 / 0.95);\n overflow-x: auto;\n }\n\n .vf-markdown-editor__mdx-block {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n padding: 6px 8px;\n }\n\n .vf-markdown-editor__mdx-block-label {\n font-size: 11px;\n color: oklch(0.2768 0 0);\n white-space: nowrap;\n }\n\n .vf-markdown-editor__mdx-note {\n font-size: 10px;\n color: oklch(0.55 0.005 95.11);\n white-space: nowrap;\n }\n\n .vf-markdown-editor__mdx-open {\n border: 1px solid oklch(0.84 0.0055 95.11);\n border-radius: 6px;\n background: oklch(1 0 0);\n color: oklch(0.2768 0 0);\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n line-height: 1;\n padding: 5px 7px;\n cursor: pointer;\n white-space: nowrap;\n transition: background 75ms ease;\n }\n .vf-markdown-editor__mdx-open:hover {\n background: oklch(0.93 0 0);\n }\n\n /* ------------------------------------------------------------------ */\n /* Lexical surface overrides */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__surface [data-lexical-editor] {\n outline: none;\n }\n\n .vf-markdown-editor__surface s,\n .vf-markdown-editor__surface del,\n .vf-markdown-editor__surface [style*='line-through'] {\n text-decoration: line-through;\n }\n\n .vf-markdown-editor__surface p:empty::before {\n content: \"Type '/' for commands\";\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n font-style: normal;\n }\n\n .vf-markdown-editor__surface h1:empty::before {\n content: 'Heading 1';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface h2:empty::before {\n content: 'Heading 2';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface h3:empty::before {\n content: 'Heading 3';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface blockquote:empty::before {\n content: 'Quote';\n color: oklch(0.55 0.005 95.11 / 0.6);\n pointer-events: none;\n }\n\n .vf-markdown-editor__surface p {\n min-height: 1.5em;\n }\n\n /* ------------------------------------------------------------------ */\n /* Textarea fallback */\n /* ------------------------------------------------------------------ */\n\n .vf-markdown-editor__textarea {\n width: 100%;\n height: 100vh;\n border: 0;\n outline: none;\n resize: none;\n display: none;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;\n font-size: 14px;\n line-height: 1.6;\n color: oklch(0.2768 0 0);\n background: transparent;\n padding: 16px;\n box-sizing: border-box;\n }\n\n /* ================================================================== */\n /* DARK MODE */\n /* ================================================================== */\n\n [data-theme='dark'] .vf-markdown-editor {\n background: oklch(0.2768 0 0);\n }\n\n [data-theme='dark'] .vf-markdown-editor__history {\n background: oklch(0.3211 0 0);\n border-color: oklch(0.42 0.0017 106.48);\n color: oklch(0.9512 0.008 98.88);\n }\n [data-theme='dark'] .vf-markdown-editor__history:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__textarea {\n color: oklch(0.9512 0.008 98.88);\n }\n\n /* Slash menu \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__slash-menu {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.21 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-section {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-item:hover,\n [data-theme='dark'] .vf-markdown-editor__slash-item[data-active='true'] {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-icon {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-item-title {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-shortcut {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-footer {\n border-top-color: oklch(0.3 0.01 220);\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__slash-footer-key {\n border-color: oklch(0.42 0.0017 106.48);\n color: oklch(0.5338 0.0046 106.55);\n }\n\n /* Inline toolbar \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__inline-toolbar {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.21 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-separator {\n background: oklch(0.3 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-button {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-button:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__inline-button.active {\n background: oklch(0.6852 0.162 241.8 / 0.2);\n color: oklch(0.75 0.14 241.8);\n }\n\n /* Block trigger \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__block-trigger {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-trigger:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-trigger::after {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n /* Block dropdown \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__block-dropdown {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.21 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-option {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-option:hover {\n background: oklch(0.25 0.01 220);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-option.active {\n background: oklch(0.6852 0.162 241.8 / 0.2);\n color: oklch(0.75 0.14 241.8);\n }\n\n /* Placeholder text \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__surface p:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface h1:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface h2:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface h3:empty::before,\n [data-theme='dark'] .vf-markdown-editor__surface blockquote:empty::before {\n color: oklch(0.5338 0.0046 106.55 / 0.5);\n }\n\n /* Block drag \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__block-handle {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-handle:hover {\n background: oklch(0.6852 0.162 241.8 / 0.2);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drop-label {\n border-color: oklch(0.6852 0.162 241.8 / 0.35);\n background: oklch(0.18 0.01 220 / 0.96);\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drag-ghost {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drag-ghost-title {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__block-drag-ghost-text {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n /* MDX blocks \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-editor__mdx-blocks {\n border-bottom-color: oklch(0.3 0.01 220);\n background: oklch(0.18 0.01 220 / 0.8);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-block {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.3211 0 0);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-block-label {\n color: oklch(0.9512 0.008 98.88);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-note {\n color: oklch(0.5338 0.0046 106.55);\n }\n\n [data-theme='dark'] .vf-markdown-editor__mdx-open {\n border-color: oklch(0.42 0.0017 106.48);\n background: oklch(0.2768 0 0);\n color: oklch(0.9512 0.008 98.88);\n }\n [data-theme='dark'] .vf-markdown-editor__mdx-open:hover {\n background: oklch(0.25 0.01 220);\n }\n\n /* Edit button \\u2013 dark */\n\n [data-theme='dark'] .vf-markdown-edit-button {\n background: oklch(0.9512 0.008 98.88);\n color: oklch(0.2768 0 0);\n border-color: oklch(0.42 0.0017 106.48);\n }\n`;\nfunction injectOverlayStyles() {\n if (document.getElementById(\"vf-overlay-styles\")) return;\n const style = document.createElement(\"style\");\n style.id = \"vf-overlay-styles\";\n style.textContent = OVERLAY_CSS;\n try {\n document.head.appendChild(style);\n if (!style.sheet) {\n logger.warn(\"Inline style injection may be blocked by CSP (style-src)\");\n }\n } catch (error) {\n logger.warn(\n \"Failed to inject bridge styles. This may be caused by CSP style-src restrictions.\",\n error instanceof Error ? error : {\n error: String(error)\n }\n );\n }\n}\n\n// src/studio/bridge/bridge-constants.ts\nvar DATA_VF_ID = \"data-vf-id\";\nvar DATA_VF_SELECTOR = \"data-vf-selector\";\nvar DATA_VF_TEXT = \"data-vf-text\";\nvar DATA_VF_IGNORE = \"data-vf-ignore\";\nvar DATA_NODE_ID = \"data-node-id\";\nvar DATA_NODE_FILE = \"data-node-file\";\nvar DATA_NODE_NAME = \"data-node-name\";\nvar DATA_NODE_LINE = \"data-node-line\";\nvar DATA_NODE_COLUMN = \"data-node-column\";\nvar DATA_NODE_SOURCE = \"data-node-source\";\n\n// src/studio/bridge/bridge-utils.ts\nfunction debounce(fn, ms) {\n let timer;\n const debounced = function(...args) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n fn.apply(this, args);\n }, ms);\n };\n debounced.cancel = () => {\n clearTimeout(timer);\n timer = void 0;\n };\n return debounced;\n}\n\n// src/studio/bridge/bridge-inspector.ts\nfunction createOverlay(type) {\n const overlay = document.createElement(\"div\");\n overlay.className = \"vf-overlay vf-overlay-\" + type;\n overlay.setAttribute(DATA_VF_IGNORE, \"true\");\n const label = document.createElement(\"div\");\n label.className = \"vf-overlay-label\";\n overlay.appendChild(label);\n overlay.style.display = \"none\";\n document.body.appendChild(overlay);\n return overlay;\n}\nfunction hideOverlay(overlay) {\n if (overlay) overlay.style.display = \"none\";\n}\nfunction positionOverlay(overlay, element, nodeName) {\n if (!overlay) return;\n if (!element) {\n hideOverlay(overlay);\n return;\n }\n const rect = element.getBoundingClientRect();\n overlay.style.display = \"block\";\n overlay.style.top = rect.top + \"px\";\n overlay.style.left = rect.left + \"px\";\n overlay.style.width = rect.width + \"px\";\n overlay.style.height = rect.height + \"px\";\n const label = overlay.querySelector(\".vf-overlay-label\");\n if (label) {\n label.textContent = nodeName;\n if (rect.top < 24) {\n label.classList.add(\"vf-overlay-label-bottom\");\n } else {\n label.classList.remove(\"vf-overlay-label-bottom\");\n }\n }\n}\nfunction getNodeName(element) {\n const vfId = element.getAttribute(DATA_VF_ID);\n if (vfId) return vfId.split(\"_\")[0] ?? vfId;\n return element.tagName.toLowerCase();\n}\nfunction findElementById(nodeId) {\n if (!nodeId) return null;\n return document.querySelector(\"[\" + DATA_VF_ID + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_VF_SELECTOR + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_NODE_ID + '=\"' + nodeId + '\"]');\n}\nfunction isValidElement(el) {\n return !!el && el.nodeType === Node.ELEMENT_NODE && !DOM_IGNORE_TAGS.includes(el.tagName) && !el.hasAttribute(DATA_VF_IGNORE) && el.style.display !== \"none\";\n}\nfunction getNodeType(el) {\n const vfId = el.getAttribute(DATA_VF_ID) || \"\";\n if (vfId && /^[A-Z]/.test(vfId)) return \"component\";\n if (el.hasAttribute(DATA_VF_TEXT)) return \"text\";\n if (el.getAttribute(DATA_NODE_SOURCE) === \"md\") return \"markdown\";\n return \"element\";\n}\nfunction buildNavigatorTree(root) {\n const config3 = getConfig();\n let nodeIndex = 0;\n function processElement(el, parentId) {\n if (!isValidElement(el)) {\n const children = [];\n Array.from(el.children || []).forEach((child) => {\n children.push(...processElement(child, parentId));\n });\n return children;\n }\n let id = el.getAttribute(DATA_VF_ID) || el.getAttribute(DATA_NODE_ID) || el.getAttribute(DATA_VF_SELECTOR);\n if (!id) {\n id = \"vf-\" + el.tagName.toLowerCase() + \"-\" + ++nodeIndex;\n el.setAttribute(DATA_VF_SELECTOR, id);\n }\n const vfId = el.getAttribute(DATA_VF_ID);\n const name = vfId ? vfId.split(\"_\")[0] ?? vfId : el.tagName.toLowerCase();\n const node = {\n id,\n name,\n type: getNodeType(el),\n path: config3.pagePath,\n parentId,\n start: {\n line: parseInt(el.getAttribute(DATA_NODE_LINE) || \"0\", 10),\n column: parseInt(el.getAttribute(DATA_NODE_COLUMN) || \"0\", 10)\n },\n end: { line: 0, column: 0 },\n children: [],\n text: el.hasAttribute(DATA_VF_TEXT) ? el.textContent?.trim() : void 0,\n isRemote: false\n };\n Array.from(el.children || []).forEach((child) => {\n node.children.push(...processElement(child, id));\n });\n return [node];\n }\n const rootNode = {\n id: \"root\",\n name: \"root\",\n type: \"root\",\n path: \"\",\n parentId: \"\",\n start: { line: 0, column: 0 },\n end: { line: 0, column: 0 },\n children: [],\n isRemote: false\n };\n Array.from(root.children || []).forEach((child) => {\n rootNode.children.push(...processElement(child, \"root\"));\n });\n return rootNode;\n}\nfunction createTreeSignature(root) {\n const validElements = Array.from(root.querySelectorAll(\"*\")).filter((el) => isValidElement(el));\n return validElements.length + \"-\" + validElements.map((el) => el.tagName).join(\"\");\n}\nvar treeUpdateTimer = null;\nvar mutationObserver = null;\nfunction sendTreeUpdate() {\n const config3 = getConfig();\n const root = document.getElementById(\"root\") || document.body;\n if (!root) return;\n const signature = createTreeSignature(root);\n if (signature === state.lastTreeSignature) return;\n state.lastTreeSignature = signature;\n postToStudio({\n action: \"treeUpdated\",\n id: config3.pageId,\n url: window.location.href,\n tree: buildNavigatorTree(root),\n sourceHash: globalThis.__VERYFRONT_SOURCE_HASH__ || null\n });\n}\nfunction debouncedTreeUpdate() {\n if (treeUpdateTimer) clearTimeout(treeUpdateTimer);\n treeUpdateTimer = setTimeout(sendTreeUpdate, 150);\n}\nfunction setupMutationObserver() {\n const root = document.getElementById(\"root\") || document.body;\n if (!root) return;\n mutationObserver = new MutationObserver(function(mutations) {\n const hasRelevantChanges = mutations.some(\n (m) => m.type === \"childList\" || m.type === \"characterData\"\n );\n if (!hasRelevantChanges) return;\n if (state.selectedNodeId && !findElementById(state.selectedNodeId)) {\n state.selectedNodeId = null;\n hideOverlay(state.selectionOverlay);\n postToStudio({ action: \"setSelectedNode\", id: null });\n }\n debouncedTreeUpdate();\n });\n mutationObserver.observe(root, { childList: true, characterData: true, subtree: true });\n sendTreeUpdate();\n}\nfunction showOverlay(overlay, nodeId) {\n if (!nodeId) {\n hideOverlay(overlay);\n return;\n }\n const el = findElementById(nodeId);\n if (!el) {\n hideOverlay(overlay);\n return;\n }\n positionOverlay(overlay, el, getNodeName(el));\n}\nfunction showHoverOverlay(nodeId) {\n showOverlay(state.hoverOverlay, nodeId);\n}\nfunction showSelectionOverlay(nodeId) {\n showOverlay(state.selectionOverlay, nodeId);\n}\nfunction scrollToElement(nodeId) {\n const el = document.querySelector(\"[\" + DATA_VF_ID + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_NODE_ID + '=\"' + nodeId + '\"]') || document.querySelector(\"[\" + DATA_VF_SELECTOR + '*=\"' + nodeId + '\"]');\n if (el) el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n}\nfunction getDirectText(el) {\n let text = \"\";\n for (let i = 0; i < el.childNodes.length; i++) {\n const node = el.childNodes[i];\n if (node?.nodeType === Node.TEXT_NODE) {\n text += node.textContent || \"\";\n }\n }\n return text.trim();\n}\nfunction setupInspectMode() {\n const INSPECTABLE_SELECTOR = \"[\" + DATA_VF_ID + \"], [\" + DATA_VF_SELECTOR + \"], [\" + DATA_NODE_ID + \"], [\" + DATA_NODE_FILE + \"]\";\n function getElementId(el) {\n return el.getAttribute(DATA_VF_ID) || el.getAttribute(DATA_NODE_ID) || el.getAttribute(DATA_VF_SELECTOR);\n }\n document.addEventListener(\n \"click\",\n function(event) {\n if (!state.inspectMode) return;\n event.preventDefault();\n event.stopPropagation();\n const target = event.target.closest(INSPECTABLE_SELECTOR);\n if (!target) {\n state.selectedNodeId = null;\n hideOverlay(state.selectionOverlay);\n postToStudio({ action: \"setSelectedNode\", id: null });\n return;\n }\n const id = getElementId(target);\n state.selectedNodeId = id;\n showSelectionOverlay(id);\n postToStudio({\n action: \"setSelectedNode\",\n id,\n node: {\n name: target.getAttribute(DATA_NODE_NAME) || target.tagName.toLowerCase(),\n type: getNodeType(target),\n file: target.getAttribute(DATA_NODE_FILE) || getConfig().pagePath,\n line: parseInt(target.getAttribute(DATA_NODE_LINE) || \"0\", 10),\n column: parseInt(target.getAttribute(DATA_NODE_COLUMN) || \"0\", 10),\n text: getDirectText(target).slice(0, 200)\n }\n });\n },\n true\n );\n document.addEventListener(\"pointerover\", function(event) {\n if (!state.inspectMode || event.pointerType === \"touch\") return;\n const target = event.target.closest(INSPECTABLE_SELECTOR);\n if (!target) return;\n const id = getElementId(target);\n if (id === state.hoveredNodeId) return;\n state.hoveredNodeId = id;\n showHoverOverlay(id);\n });\n document.addEventListener(\"pointerout\", function(event) {\n if (!state.inspectMode || event.pointerType === \"touch\") return;\n const target = event.target.closest(INSPECTABLE_SELECTOR);\n if (!target) return;\n const relatedTarget = event.relatedTarget;\n if (relatedTarget && target.contains(relatedTarget)) return;\n state.hoveredNodeId = null;\n hideOverlay(state.hoverOverlay);\n });\n const updateOverlays = debounce(function() {\n if (state.inspectMode && state.hoveredNodeId) showHoverOverlay(state.hoveredNodeId);\n if (state.selectedNodeId) showSelectionOverlay(state.selectedNodeId);\n }, 16);\n window.addEventListener(\"scroll\", updateOverlays, true);\n window.addEventListener(\"resize\", updateOverlays);\n}\nfunction setColorMode(mode) {\n document.documentElement.setAttribute(\"data-theme\", mode);\n document.documentElement.classList.remove(\"light\", \"dark\");\n document.documentElement.classList.add(mode);\n}\n\n// src/studio/bridge/bridge-console.ts\nfunction setupConsoleCapture() {\n const consoleObj = console;\n CONSOLE_METHODS.forEach((method) => {\n state.originalConsole[method] = consoleObj[method];\n consoleObj[method] = function(...args) {\n state.originalConsole[method].apply(console, args);\n const logId = \"vf-\" + Date.now() + \"-\" + ++state.logCounter;\n const formattedData = args.map((arg) => {\n try {\n if (arg instanceof Error) {\n return { __isError: true, message: arg.message, stack: arg.stack, name: arg.name };\n }\n if (arg === void 0) return { __isUndefined: true };\n if (arg === null) return null;\n if (typeof arg === \"function\") {\n return { __isFunction: true, name: arg.name || \"anonymous\" };\n }\n if (typeof arg === \"symbol\") return { __isSymbol: true, description: arg.description };\n if (typeof arg === \"object\") return JSON.parse(JSON.stringify(arg));\n return arg;\n } catch (_) {\n return String(arg);\n }\n });\n postToStudio({\n action: \"logEvent\",\n value: {\n id: logId,\n method,\n data: formattedData,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n }\n });\n };\n });\n}\nfunction setupErrorHandling() {\n function hideOverlays() {\n hideOverlay(state.hoverOverlay);\n hideOverlay(state.selectionOverlay);\n }\n window.addEventListener(\"error\", function(event) {\n hideOverlays();\n postToStudio({\n action: \"runtimeError\",\n url: window.location.href,\n errors: [\n {\n type: \"error\",\n message: event.message,\n file: event.filename,\n line: event.lineno,\n column: event.colno\n }\n ]\n });\n });\n window.addEventListener(\"unhandledrejection\", function(event) {\n hideOverlays();\n const reason = event.reason;\n postToStudio({\n action: \"runtimeError\",\n url: window.location.href,\n errors: [\n {\n type: \"error\",\n message: reason instanceof Error ? reason.message : String(reason),\n file: reason instanceof Error ? reason.stack : void 0\n }\n ]\n });\n });\n}\n\n// src/studio/bridge/bridge-screenshot.ts\nfunction loadHtml2Canvas() {\n if (state.html2canvasLoaded) return Promise.resolve();\n if (state.html2canvasPromise) return state.html2canvasPromise;\n state.html2canvasPromise = new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = \"https://cdn.jsdelivr.net/npm/html2canvas-pro@2.0.0/dist/html2canvas-pro.min.js\";\n script.onload = () => {\n state.html2canvasLoaded = true;\n resolve();\n };\n script.onerror = (event) => {\n logger.warn(\n \"Failed to load html2canvas script. This may be caused by CSP script-src restrictions.\",\n { event: String(event) }\n );\n reject(new Error(\"Failed to load html2canvas script\"));\n };\n try {\n document.head.appendChild(script);\n } catch (error) {\n logger.warn(\n \"Failed to append html2canvas script element. This may be caused by CSP script-src restrictions.\",\n error instanceof Error ? error : { error: String(error) }\n );\n reject(\n error instanceof Error ? error : new Error(\"Failed to append html2canvas script element\")\n );\n }\n });\n return state.html2canvasPromise;\n}\nasync function captureScreenshot(options) {\n const { scrollTo, fullPage, quality = 0.8 } = options || {};\n const originalScrollY = window.scrollY;\n try {\n await loadHtml2Canvas();\n if (typeof scrollTo === \"number\") {\n window.scrollTo(0, scrollTo);\n await new Promise((r) => setTimeout(r, 150));\n }\n const canvasOptions = {\n useCORS: true,\n logging: false,\n scale: window.devicePixelRatio || 1\n };\n if (fullPage) {\n canvasOptions.height = document.documentElement.scrollHeight;\n canvasOptions.windowHeight = document.documentElement.scrollHeight;\n canvasOptions.y = 0;\n window.scrollTo(0, 0);\n await new Promise((r) => setTimeout(r, 100));\n }\n const html2canvasFn = window.html2canvas.default || window.html2canvas;\n const canvas = await html2canvasFn(document.body, canvasOptions);\n if (!canvas || canvas.width === 0 || canvas.height === 0) {\n logger.error(\"html2canvas produced empty canvas\", {\n width: canvas?.width,\n height: canvas?.height\n });\n window.scrollTo(0, originalScrollY);\n return {\n success: false,\n error: \"html2canvas produced empty canvas (0x0 dimensions)\"\n };\n }\n const dataUrl = canvas.toDataURL(\"image/png\", quality);\n if (!dataUrl || !dataUrl.startsWith(\"data:image/\") || dataUrl.length < 100) {\n logger.error(\"html2canvas produced invalid data URL\", {\n dataUrlPreview: dataUrl?.substring(0, 50)\n });\n window.scrollTo(0, originalScrollY);\n return {\n success: false,\n error: \"html2canvas produced invalid image data\"\n };\n }\n window.scrollTo(0, originalScrollY);\n return {\n success: true,\n data: dataUrl,\n width: canvas.width,\n height: canvas.height,\n scrollY: window.scrollY,\n totalHeight: document.documentElement.scrollHeight,\n viewportHeight: window.innerHeight,\n url: window.location.href\n };\n } catch (error) {\n logger.error(\"html2canvas error\", error instanceof Error ? error : { error: String(error) });\n window.scrollTo(0, originalScrollY);\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n}\nasync function captureMultipleSections(sectionCount) {\n const originalScrollY = window.scrollY;\n const results = [];\n const totalHeight = document.documentElement.scrollHeight;\n const viewportHeight = window.innerHeight;\n const sections = sectionCount || Math.ceil(totalHeight / viewportHeight);\n try {\n for (let i = 0; i < sections; i++) {\n const scrollY = Math.min(i * viewportHeight, totalHeight - viewportHeight);\n const result = await captureScreenshot({ scrollTo: scrollY });\n if (result.success) {\n results.push({ ...result, section: i + 1, totalSections: sections });\n }\n }\n } finally {\n window.scrollTo(0, originalScrollY);\n }\n return results;\n}\n\n// src/studio/bridge/bridge-message-handler.ts\nvar SAFE_PROTOCOLS = /* @__PURE__ */ new Set([\"http:\", \"https:\"]);\nfunction isSafeNavigationUrl(url) {\n if (url.startsWith(\"/\")) return true;\n try {\n const parsed = new URL(url, window.location.origin);\n return SAFE_PROTOCOLS.has(parsed.protocol);\n } catch {\n return false;\n }\n}\nfunction clearSelection(notifyStudio = false) {\n state.selectedNodeId = null;\n hideOverlay(state.selectionOverlay);\n if (notifyStudio) {\n postToStudio({ action: \"setSelectedNode\", id: null });\n }\n}\nfunction disableInspectMode(deselectElements = false) {\n state.inspectMode = false;\n hideOverlay(state.hoverOverlay);\n state.hoveredNodeId = null;\n if (deselectElements) {\n clearSelection();\n }\n}\nfunction postScreenshotResult(requestId, result) {\n postToStudio({\n action: \"screenshotResult\",\n requestId,\n multiple: false,\n ...result\n });\n}\nasync function handleScreenshotRequest(message) {\n if (message.multipleSections) {\n const results = await captureMultipleSections(message.sectionCount);\n postToStudio({\n action: \"screenshotResult\",\n requestId: message.requestId,\n multiple: true,\n results\n });\n return;\n }\n const result = await captureScreenshot(message.options);\n postScreenshotResult(message.requestId, result);\n}\nfunction handleStudioMessage(event) {\n if (!isFromStudio(event)) return;\n const message = event.data;\n if (!message?.action) return;\n const config3 = getConfig();\n switch (message.action) {\n case \"routeChange\":\n if (message.url) {\n if (!isSafeNavigationUrl(message.url)) {\n logger.warn(\"[StudioBridge] Blocked unsafe URL in routeChange\", { url: message.url });\n return;\n }\n if (state.selectedNodeId) {\n clearSelection(true);\n }\n postToStudio({\n action: \"onPageTransitionStart\",\n url: message.url,\n projectId: config3.projectId\n });\n window.location.href = message.url;\n }\n return;\n case \"reload\":\n window.location.reload();\n return;\n case \"goBack\":\n window.history.back();\n return;\n case \"goForward\":\n window.history.forward();\n return;\n case \"colorMode\":\n setColorMode(message.value);\n return;\n case \"toggleInspectMode\":\n state.inspectMode = message.value;\n if (state.inspectMode) return;\n disableInspectMode(message.deselectElements);\n return;\n case \"setSelectedNode\":\n state.selectedNodeId = message.id;\n showSelectionOverlay(message.id);\n if (message.scroll) scrollToElement(message.id);\n return;\n case \"setHoveredNode\":\n if (!state.inspectMode) showHoverOverlay(message.id);\n return;\n case \"screenshot\":\n void handleScreenshotRequest(message);\n return;\n default:\n logger.debug(\"Unknown action\", { action: message.action });\n return;\n }\n}\n\n// src/studio/bridge/bridge-init.ts\nfunction notifyAppLoaded() {\n const config3 = getConfig();\n postToStudio({ action: \"appLoaded\", url: window.location.href });\n postToStudio({\n action: \"appUpdated\",\n url: window.location.href,\n id: config3.pageId,\n isInitialLoad: true,\n errors: [],\n warnings: []\n });\n postToStudio({\n action: \"onPageTransitionEnd\",\n url: window.location.href,\n projectId: config3.projectId,\n id: config3.pageId,\n params: {}\n });\n}\nfunction notifyAppUnloaded() {\n postToStudio({ action: \"appUnloaded\", url: window.location.href });\n}\nfunction init() {\n const config3 = getConfig();\n const params = new URLSearchParams(window.location.search);\n const studioEmbed = params.get(\"studio_embed\") === \"true\";\n const isStandalone = window.parent === window && !studioEmbed;\n if (isStandalone) {\n logger.debug(\n \"[StudioBridge] Not in iframe and not studio_embed mode, skipping initialization\"\n );\n return;\n }\n logger.debug(\"Initializing...\");\n if (!isStandalone) {\n injectOverlayStyles();\n state.hoverOverlay = createOverlay(\"hover\");\n state.selectionOverlay = createOverlay(\"selection\");\n setupConsoleCapture();\n setupErrorHandling();\n setupInspectMode();\n }\n window.addEventListener(\"message\", handleStudioMessage);\n if (!isStandalone) {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", function() {\n notifyAppLoaded();\n setupMutationObserver();\n }, { once: true });\n } else {\n notifyAppLoaded();\n setupMutationObserver();\n }\n window.addEventListener(\"beforeunload\", notifyAppUnloaded, { once: true });\n }\n const colorMode = params.get(\"color_mode\");\n if (colorMode) setColorMode(colorMode);\n if (!isStandalone) {\n const inspectModeParam = params.get(\"inspect_mode\");\n if (inspectModeParam === \"true\") {\n state.inspectMode = true;\n logger.debug(\"Inspect mode enabled from query param\");\n }\n }\n logger.debug(\"Initialized successfully\");\n}\n\n// src/studio/bridge/bridge-coordinator.ts\ninitConfig();\nvar config2 = getConfig();\nif (!config2.debugSkipInit) {\n init();\n}\n";
|
|
@@ -30,6 +30,14 @@ import type { TaskDefinition } from "./types.js";
|
|
|
30
30
|
import { isTaskDefinition } from "./types.js";
|
|
31
31
|
|
|
32
32
|
const logger = baseLogger.component("task-discovery");
|
|
33
|
+
const TASK_FILE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"] as const;
|
|
34
|
+
const TASK_IGNORE_PATTERNS = [
|
|
35
|
+
"node_modules",
|
|
36
|
+
".git",
|
|
37
|
+
"__tests__",
|
|
38
|
+
"*.test.*",
|
|
39
|
+
"*.spec.*",
|
|
40
|
+
] as const;
|
|
33
41
|
|
|
34
42
|
/**
|
|
35
43
|
* Discovered task info
|
|
@@ -82,6 +90,76 @@ export interface TaskDiscoveryResult {
|
|
|
82
90
|
errors: Array<{ filePath: string; error: string }>;
|
|
83
91
|
}
|
|
84
92
|
|
|
93
|
+
function resolveTasksBaseDir(
|
|
94
|
+
projectDir: string,
|
|
95
|
+
tasksDir: string,
|
|
96
|
+
config?: VeryfrontConfig,
|
|
97
|
+
): string {
|
|
98
|
+
const fsType = config?.fs?.type ?? "local";
|
|
99
|
+
return fsType === "github" || fsType === "veryfront-api" ? tasksDir : join(projectDir, tasksDir);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function toErrorMessage(error: unknown): string {
|
|
103
|
+
return error instanceof Error ? error.message : String(error);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function collectTaskFiles(baseDir: string, adapter: RuntimeAdapter): Promise<
|
|
107
|
+
Awaited<ReturnType<typeof collectFiles>>
|
|
108
|
+
> {
|
|
109
|
+
return await collectFiles({
|
|
110
|
+
baseDir,
|
|
111
|
+
extensions: [...TASK_FILE_EXTENSIONS],
|
|
112
|
+
recursive: true,
|
|
113
|
+
ignorePatterns: [...TASK_IGNORE_PATTERNS],
|
|
114
|
+
adapter,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function extractTaskExport(
|
|
119
|
+
module: Record<string, unknown>,
|
|
120
|
+
): { exportName: string; definition: TaskDefinition } | null {
|
|
121
|
+
const defaultExport = module.default;
|
|
122
|
+
if (isTaskDefinition(defaultExport)) {
|
|
123
|
+
return { exportName: "default", definition: defaultExport };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
for (const [exportName, value] of Object.entries(module)) {
|
|
127
|
+
if (exportName !== "default" && isTaskDefinition(value)) {
|
|
128
|
+
return { exportName, definition: value };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function loadTaskFromFile(
|
|
136
|
+
filePath: string,
|
|
137
|
+
id: string,
|
|
138
|
+
adapter: RuntimeAdapter,
|
|
139
|
+
projectDir: string,
|
|
140
|
+
): Promise<DiscoveredTask | null> {
|
|
141
|
+
const module = await importDiscoveryModule(filePath, {
|
|
142
|
+
adapter,
|
|
143
|
+
projectDir,
|
|
144
|
+
}) as Record<string, unknown>;
|
|
145
|
+
const taskExport = extractTaskExport(module);
|
|
146
|
+
if (!taskExport) return null;
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
id,
|
|
150
|
+
name: taskExport.definition.name || id,
|
|
151
|
+
filePath,
|
|
152
|
+
exportName: taskExport.exportName,
|
|
153
|
+
definition: taskExport.definition,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function logDiscoveredTask(task: DiscoveredTask, debug: boolean): void {
|
|
158
|
+
if (debug) {
|
|
159
|
+
logger.info(`Found task "${task.id}" in ${task.filePath} (export: ${task.exportName})`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
85
163
|
/**
|
|
86
164
|
* Derive task ID from file path (e.g., "tasks/sync-data.ts" → "sync-data")
|
|
87
165
|
*/
|
|
@@ -112,10 +190,7 @@ export async function discoverTasks(
|
|
|
112
190
|
|
|
113
191
|
const tasks: DiscoveredTask[] = [];
|
|
114
192
|
const errors: Array<{ filePath: string; error: string }> = [];
|
|
115
|
-
|
|
116
|
-
const fsType = config?.fs?.type ?? "local";
|
|
117
|
-
const useRelativePaths = fsType === "github" || fsType === "veryfront-api";
|
|
118
|
-
const baseDir = useRelativePaths ? tasksDir : join(projectDir, tasksDir);
|
|
193
|
+
const baseDir = resolveTasksBaseDir(projectDir, tasksDir, config);
|
|
119
194
|
|
|
120
195
|
if (debug) {
|
|
121
196
|
logger.info(`Scanning ${baseDir} for tasks`);
|
|
@@ -130,13 +205,7 @@ export async function discoverTasks(
|
|
|
130
205
|
return { tasks, errors };
|
|
131
206
|
}
|
|
132
207
|
|
|
133
|
-
const files = await
|
|
134
|
-
baseDir,
|
|
135
|
-
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
136
|
-
recursive: true,
|
|
137
|
-
ignorePatterns: ["node_modules", ".git", "__tests__", "*.test.*", "*.spec.*"],
|
|
138
|
-
adapter,
|
|
139
|
-
});
|
|
208
|
+
const files = await collectTaskFiles(baseDir, adapter);
|
|
140
209
|
|
|
141
210
|
if (debug) {
|
|
142
211
|
logger.info(`Found ${files.length} potential task files`);
|
|
@@ -144,49 +213,18 @@ export async function discoverTasks(
|
|
|
144
213
|
|
|
145
214
|
for (const file of files) {
|
|
146
215
|
try {
|
|
147
|
-
const
|
|
216
|
+
const task = await loadTaskFromFile(
|
|
217
|
+
file.path,
|
|
218
|
+
deriveTaskId(file.path, baseDir),
|
|
148
219
|
adapter,
|
|
149
220
|
projectDir,
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (isTaskDefinition(defaultExport)) {
|
|
155
|
-
const id = deriveTaskId(file.path, baseDir);
|
|
156
|
-
tasks.push({
|
|
157
|
-
id,
|
|
158
|
-
name: defaultExport.name || id,
|
|
159
|
-
filePath: file.path,
|
|
160
|
-
exportName: "default",
|
|
161
|
-
definition: defaultExport,
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
if (debug) {
|
|
165
|
-
logger.info(`Found task "${id}" in ${file.path} (export: default)`);
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
168
|
-
// Fallback: check named exports
|
|
169
|
-
for (const [exportName, value] of Object.entries(module)) {
|
|
170
|
-
if (exportName === "default") continue;
|
|
171
|
-
if (isTaskDefinition(value)) {
|
|
172
|
-
const id = deriveTaskId(file.path, baseDir);
|
|
173
|
-
tasks.push({
|
|
174
|
-
id,
|
|
175
|
-
name: value.name || id,
|
|
176
|
-
filePath: file.path,
|
|
177
|
-
exportName,
|
|
178
|
-
definition: value,
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
if (debug) {
|
|
182
|
-
logger.info(`Found task "${id}" in ${file.path} (export: ${exportName})`);
|
|
183
|
-
}
|
|
184
|
-
break; // Only take the first valid named export per file
|
|
185
|
-
}
|
|
186
|
-
}
|
|
221
|
+
);
|
|
222
|
+
if (task) {
|
|
223
|
+
tasks.push(task);
|
|
224
|
+
logDiscoveredTask(task, debug);
|
|
187
225
|
}
|
|
188
226
|
} catch (error) {
|
|
189
|
-
const errorMsg =
|
|
227
|
+
const errorMsg = toErrorMessage(error);
|
|
190
228
|
errors.push({ filePath: file.path, error: errorMsg });
|
|
191
229
|
|
|
192
230
|
if (debug) {
|
|
@@ -201,7 +239,7 @@ export async function discoverTasks(
|
|
|
201
239
|
|
|
202
240
|
return { tasks, errors };
|
|
203
241
|
} catch (error) {
|
|
204
|
-
const errorMsg =
|
|
242
|
+
const errorMsg = toErrorMessage(error);
|
|
205
243
|
logger.error(`Task discovery failed: ${errorMsg}`);
|
|
206
244
|
errors.push({ filePath: baseDir, error: errorMsg });
|
|
207
245
|
return { tasks, errors };
|
|
@@ -222,71 +260,33 @@ export async function findTaskById(
|
|
|
222
260
|
tasksDir = "tasks",
|
|
223
261
|
debug = false,
|
|
224
262
|
} = options;
|
|
225
|
-
|
|
226
|
-
const fsType = config?.fs?.type ?? "local";
|
|
227
|
-
const useRelativePaths = fsType === "github" || fsType === "veryfront-api";
|
|
228
|
-
const baseDir = useRelativePaths ? tasksDir : join(projectDir, tasksDir);
|
|
263
|
+
const baseDir = resolveTasksBaseDir(projectDir, tasksDir, config);
|
|
229
264
|
|
|
230
265
|
try {
|
|
231
266
|
const dirExists = await adapter.fs.exists(baseDir);
|
|
232
267
|
if (!dirExists) return null;
|
|
233
268
|
|
|
234
|
-
const files = await
|
|
235
|
-
baseDir,
|
|
236
|
-
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
237
|
-
recursive: true,
|
|
238
|
-
ignorePatterns: ["node_modules", ".git", "__tests__", "*.test.*", "*.spec.*"],
|
|
239
|
-
adapter,
|
|
240
|
-
});
|
|
269
|
+
const files = await collectTaskFiles(baseDir, adapter);
|
|
241
270
|
|
|
242
271
|
for (const file of files) {
|
|
243
272
|
const id = deriveTaskId(file.path, baseDir);
|
|
244
273
|
if (id !== taskId) continue;
|
|
245
274
|
|
|
246
275
|
try {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const defaultExport = module.default;
|
|
253
|
-
if (isTaskDefinition(defaultExport)) {
|
|
254
|
-
if (debug) {
|
|
255
|
-
logger.info(`Found task "${id}" in ${file.path} (export: default)`);
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
id,
|
|
259
|
-
name: defaultExport.name || id,
|
|
260
|
-
filePath: file.path,
|
|
261
|
-
exportName: "default",
|
|
262
|
-
definition: defaultExport,
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
for (const [exportName, value] of Object.entries(module)) {
|
|
267
|
-
if (exportName === "default") continue;
|
|
268
|
-
if (isTaskDefinition(value)) {
|
|
269
|
-
if (debug) {
|
|
270
|
-
logger.info(`Found task "${id}" in ${file.path} (export: ${exportName})`);
|
|
271
|
-
}
|
|
272
|
-
return {
|
|
273
|
-
id,
|
|
274
|
-
name: value.name || id,
|
|
275
|
-
filePath: file.path,
|
|
276
|
-
exportName,
|
|
277
|
-
definition: value,
|
|
278
|
-
};
|
|
279
|
-
}
|
|
276
|
+
const task = await loadTaskFromFile(file.path, id, adapter, projectDir);
|
|
277
|
+
if (task) {
|
|
278
|
+
logDiscoveredTask(task, debug);
|
|
279
|
+
return task;
|
|
280
280
|
}
|
|
281
281
|
} catch (error) {
|
|
282
|
-
const errorMsg =
|
|
282
|
+
const errorMsg = toErrorMessage(error);
|
|
283
283
|
if (debug) {
|
|
284
284
|
logger.warn(`Failed to load ${file.path}: ${errorMsg}`);
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
} catch (error) {
|
|
289
|
-
const errorMsg =
|
|
289
|
+
const errorMsg = toErrorMessage(error);
|
|
290
290
|
logger.error(`Task discovery failed while finding "${taskId}": ${errorMsg}`);
|
|
291
291
|
}
|
|
292
292
|
|
package/src/src/tool/executor.ts
CHANGED
|
@@ -7,14 +7,16 @@ export function executeTool(
|
|
|
7
7
|
input: unknown,
|
|
8
8
|
context?: ToolExecutionContext,
|
|
9
9
|
): Promise<unknown> {
|
|
10
|
-
const
|
|
10
|
+
const registeredTool = toolRegistry.get(toolId);
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (!registeredTool) {
|
|
13
|
+
throw toError(
|
|
14
|
+
createError({
|
|
15
|
+
type: "agent",
|
|
16
|
+
message: `Tool "${toolId}" not found`,
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
}
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
createError({
|
|
16
|
-
type: "agent",
|
|
17
|
-
message: `Tool "${toolId}" not found`,
|
|
18
|
-
}),
|
|
19
|
-
);
|
|
21
|
+
return registeredTool.execute(input, context);
|
|
20
22
|
}
|
package/src/src/tool/factory.ts
CHANGED
|
@@ -14,6 +14,10 @@ interface ZodLikeSchema {
|
|
|
14
14
|
parse?: (input: unknown) => void;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
interface SchemaWithParse {
|
|
18
|
+
parse: (input: unknown) => unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
function hasValidZodTypeName(schema: unknown): schema is ZodLikeSchema {
|
|
18
22
|
if (schema === null || typeof schema !== "object") return false;
|
|
19
23
|
if (!("_def" in schema)) return false;
|
|
@@ -27,6 +31,10 @@ function getSchemaShape(schema: ZodLikeSchema): Record<string, unknown> | null {
|
|
|
27
31
|
return typeof shape === "function" ? shape() : shape;
|
|
28
32
|
}
|
|
29
33
|
|
|
34
|
+
function hasSchemaParse(schema: unknown): schema is SchemaWithParse {
|
|
35
|
+
return typeof (schema as { parse?: unknown } | null | undefined)?.parse === "function";
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
function buildSchemaFromShape(
|
|
31
39
|
shape: Record<string, unknown>,
|
|
32
40
|
additionalProperties = false,
|
|
@@ -52,17 +60,17 @@ function schemaError(toolId: string, message: string): never {
|
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
function tryConvert(
|
|
55
|
-
|
|
63
|
+
convertSchema: () => JsonSchema,
|
|
56
64
|
toolId: string,
|
|
57
65
|
logPrefix: string,
|
|
58
66
|
permissive: boolean,
|
|
59
|
-
|
|
60
|
-
): JsonSchema
|
|
67
|
+
failureLabel: string,
|
|
68
|
+
): JsonSchema {
|
|
61
69
|
try {
|
|
62
|
-
return
|
|
70
|
+
return convertSchema();
|
|
63
71
|
} catch (error) {
|
|
64
72
|
if (permissive) return permissiveFallback(logPrefix, toolId, "Using permissive schema");
|
|
65
|
-
schemaError(toolId, `${
|
|
73
|
+
schemaError(toolId, `${failureLabel}: ${getErrorMessage(error)}`);
|
|
66
74
|
}
|
|
67
75
|
}
|
|
68
76
|
|
|
@@ -88,10 +96,8 @@ function convertSchemaToJson(
|
|
|
88
96
|
permissive,
|
|
89
97
|
"input schema conversion failed",
|
|
90
98
|
);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return result;
|
|
94
|
-
}
|
|
99
|
+
logSchemaResult(logPrefix, toolId, "Pre-converted", result);
|
|
100
|
+
return result;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
const shape = getSchemaShape(schema as ZodLikeSchema);
|
|
@@ -103,10 +109,8 @@ function convertSchemaToJson(
|
|
|
103
109
|
permissive,
|
|
104
110
|
"schema introspection failed",
|
|
105
111
|
);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
112
|
+
logSchemaResult(logPrefix, toolId, "Introspected", result);
|
|
113
|
+
return result;
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
if (permissive) return permissiveFallback(logPrefix, toolId, "Using fully dynamic schema");
|
|
@@ -142,11 +146,9 @@ export function tool<TInput = unknown, TOutput = unknown>(
|
|
|
142
146
|
inputSchema: config.inputSchema,
|
|
143
147
|
inputSchemaJson,
|
|
144
148
|
execute: async (input: TInput, context?: ToolExecutionContext) => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (typeof schema?.parse === "function") {
|
|
149
|
+
if (hasSchemaParse(config.inputSchema)) {
|
|
148
150
|
try {
|
|
149
|
-
|
|
151
|
+
config.inputSchema.parse(input);
|
|
150
152
|
} catch (error) {
|
|
151
153
|
throw toError(
|
|
152
154
|
createError({
|
|
@@ -188,11 +190,8 @@ export function dynamicTool(config: DynamicToolConfig): Tool<unknown, unknown> {
|
|
|
188
190
|
inputSchema: config.inputSchema as z.ZodSchema<unknown>,
|
|
189
191
|
inputSchemaJson,
|
|
190
192
|
execute: async (input: unknown, context?: ToolExecutionContext) => {
|
|
191
|
-
if (
|
|
192
|
-
config.inputSchema
|
|
193
|
-
typeof (config.inputSchema as { parse?: unknown }).parse === "function"
|
|
194
|
-
) {
|
|
195
|
-
(config.inputSchema as { parse: (v: unknown) => unknown }).parse(input);
|
|
193
|
+
if (hasSchemaParse(config.inputSchema)) {
|
|
194
|
+
config.inputSchema.parse(input);
|
|
196
195
|
} else if (input === undefined) {
|
|
197
196
|
input = {};
|
|
198
197
|
} else if (input === null || typeof input !== "object") {
|