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
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* Do not edit manually — run `deno task build` to regenerate.
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
-
export const STUDIO_BRIDGE_BUNDLE = "// 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";
|
|
8
|
+
export const STUDIO_BRIDGE_BUNDLE = "// 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";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/src/task/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/src/task/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAajD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IAEX,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IAEb,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IAEnB,0BAA0B;IAC1B,UAAU,EAAE,cAAc,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IAEnB,gDAAgD;IAChD,OAAO,EAAE,cAAc,CAAC;IAExB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,eAAe,CAAC;IAEzB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,2BAA2B;IAC3B,KAAK,EAAE,cAAc,EAAE,CAAC;IAExB,0CAA0C;IAC1C,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAwED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASvE;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAiE9B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAuChC"}
|
|
@@ -25,6 +25,63 @@ import { collectFiles } from "../utils/file-discovery.js";
|
|
|
25
25
|
import { importDiscoveryModule } from "../discovery/module-import.js";
|
|
26
26
|
import { isTaskDefinition } from "./types.js";
|
|
27
27
|
const logger = baseLogger.component("task-discovery");
|
|
28
|
+
const TASK_FILE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
|
|
29
|
+
const TASK_IGNORE_PATTERNS = [
|
|
30
|
+
"node_modules",
|
|
31
|
+
".git",
|
|
32
|
+
"__tests__",
|
|
33
|
+
"*.test.*",
|
|
34
|
+
"*.spec.*",
|
|
35
|
+
];
|
|
36
|
+
function resolveTasksBaseDir(projectDir, tasksDir, config) {
|
|
37
|
+
const fsType = config?.fs?.type ?? "local";
|
|
38
|
+
return fsType === "github" || fsType === "veryfront-api" ? tasksDir : join(projectDir, tasksDir);
|
|
39
|
+
}
|
|
40
|
+
function toErrorMessage(error) {
|
|
41
|
+
return error instanceof Error ? error.message : String(error);
|
|
42
|
+
}
|
|
43
|
+
async function collectTaskFiles(baseDir, adapter) {
|
|
44
|
+
return await collectFiles({
|
|
45
|
+
baseDir,
|
|
46
|
+
extensions: [...TASK_FILE_EXTENSIONS],
|
|
47
|
+
recursive: true,
|
|
48
|
+
ignorePatterns: [...TASK_IGNORE_PATTERNS],
|
|
49
|
+
adapter,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function extractTaskExport(module) {
|
|
53
|
+
const defaultExport = module.default;
|
|
54
|
+
if (isTaskDefinition(defaultExport)) {
|
|
55
|
+
return { exportName: "default", definition: defaultExport };
|
|
56
|
+
}
|
|
57
|
+
for (const [exportName, value] of Object.entries(module)) {
|
|
58
|
+
if (exportName !== "default" && isTaskDefinition(value)) {
|
|
59
|
+
return { exportName, definition: value };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
async function loadTaskFromFile(filePath, id, adapter, projectDir) {
|
|
65
|
+
const module = await importDiscoveryModule(filePath, {
|
|
66
|
+
adapter,
|
|
67
|
+
projectDir,
|
|
68
|
+
});
|
|
69
|
+
const taskExport = extractTaskExport(module);
|
|
70
|
+
if (!taskExport)
|
|
71
|
+
return null;
|
|
72
|
+
return {
|
|
73
|
+
id,
|
|
74
|
+
name: taskExport.definition.name || id,
|
|
75
|
+
filePath,
|
|
76
|
+
exportName: taskExport.exportName,
|
|
77
|
+
definition: taskExport.definition,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function logDiscoveredTask(task, debug) {
|
|
81
|
+
if (debug) {
|
|
82
|
+
logger.info(`Found task "${task.id}" in ${task.filePath} (export: ${task.exportName})`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
28
85
|
/**
|
|
29
86
|
* Derive task ID from file path (e.g., "tasks/sync-data.ts" → "sync-data")
|
|
30
87
|
*/
|
|
@@ -45,9 +102,7 @@ export async function discoverTasks(options) {
|
|
|
45
102
|
const { projectDir, adapter, config, tasksDir = "tasks", debug = false, } = options;
|
|
46
103
|
const tasks = [];
|
|
47
104
|
const errors = [];
|
|
48
|
-
const
|
|
49
|
-
const useRelativePaths = fsType === "github" || fsType === "veryfront-api";
|
|
50
|
-
const baseDir = useRelativePaths ? tasksDir : join(projectDir, tasksDir);
|
|
105
|
+
const baseDir = resolveTasksBaseDir(projectDir, tasksDir, config);
|
|
51
106
|
if (debug) {
|
|
52
107
|
logger.info(`Scanning ${baseDir} for tasks`);
|
|
53
108
|
}
|
|
@@ -59,61 +114,20 @@ export async function discoverTasks(options) {
|
|
|
59
114
|
}
|
|
60
115
|
return { tasks, errors };
|
|
61
116
|
}
|
|
62
|
-
const files = await
|
|
63
|
-
baseDir,
|
|
64
|
-
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
65
|
-
recursive: true,
|
|
66
|
-
ignorePatterns: ["node_modules", ".git", "__tests__", "*.test.*", "*.spec.*"],
|
|
67
|
-
adapter,
|
|
68
|
-
});
|
|
117
|
+
const files = await collectTaskFiles(baseDir, adapter);
|
|
69
118
|
if (debug) {
|
|
70
119
|
logger.info(`Found ${files.length} potential task files`);
|
|
71
120
|
}
|
|
72
121
|
for (const file of files) {
|
|
73
122
|
try {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// Prefer default export (aligned with discovery-engine behaviour)
|
|
79
|
-
const defaultExport = module.default;
|
|
80
|
-
if (isTaskDefinition(defaultExport)) {
|
|
81
|
-
const id = deriveTaskId(file.path, baseDir);
|
|
82
|
-
tasks.push({
|
|
83
|
-
id,
|
|
84
|
-
name: defaultExport.name || id,
|
|
85
|
-
filePath: file.path,
|
|
86
|
-
exportName: "default",
|
|
87
|
-
definition: defaultExport,
|
|
88
|
-
});
|
|
89
|
-
if (debug) {
|
|
90
|
-
logger.info(`Found task "${id}" in ${file.path} (export: default)`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// Fallback: check named exports
|
|
95
|
-
for (const [exportName, value] of Object.entries(module)) {
|
|
96
|
-
if (exportName === "default")
|
|
97
|
-
continue;
|
|
98
|
-
if (isTaskDefinition(value)) {
|
|
99
|
-
const id = deriveTaskId(file.path, baseDir);
|
|
100
|
-
tasks.push({
|
|
101
|
-
id,
|
|
102
|
-
name: value.name || id,
|
|
103
|
-
filePath: file.path,
|
|
104
|
-
exportName,
|
|
105
|
-
definition: value,
|
|
106
|
-
});
|
|
107
|
-
if (debug) {
|
|
108
|
-
logger.info(`Found task "${id}" in ${file.path} (export: ${exportName})`);
|
|
109
|
-
}
|
|
110
|
-
break; // Only take the first valid named export per file
|
|
111
|
-
}
|
|
112
|
-
}
|
|
123
|
+
const task = await loadTaskFromFile(file.path, deriveTaskId(file.path, baseDir), adapter, projectDir);
|
|
124
|
+
if (task) {
|
|
125
|
+
tasks.push(task);
|
|
126
|
+
logDiscoveredTask(task, debug);
|
|
113
127
|
}
|
|
114
128
|
}
|
|
115
129
|
catch (error) {
|
|
116
|
-
const errorMsg =
|
|
130
|
+
const errorMsg = toErrorMessage(error);
|
|
117
131
|
errors.push({ filePath: file.path, error: errorMsg });
|
|
118
132
|
if (debug) {
|
|
119
133
|
logger.warn(`Failed to load ${file.path}: ${errorMsg}`);
|
|
@@ -126,7 +140,7 @@ export async function discoverTasks(options) {
|
|
|
126
140
|
return { tasks, errors };
|
|
127
141
|
}
|
|
128
142
|
catch (error) {
|
|
129
|
-
const errorMsg =
|
|
143
|
+
const errorMsg = toErrorMessage(error);
|
|
130
144
|
logger.error(`Task discovery failed: ${errorMsg}`);
|
|
131
145
|
errors.push({ filePath: baseDir, error: errorMsg });
|
|
132
146
|
return { tasks, errors };
|
|
@@ -137,61 +151,25 @@ export async function discoverTasks(options) {
|
|
|
137
151
|
*/
|
|
138
152
|
export async function findTaskById(taskId, options) {
|
|
139
153
|
const { projectDir, adapter, config, tasksDir = "tasks", debug = false, } = options;
|
|
140
|
-
const
|
|
141
|
-
const useRelativePaths = fsType === "github" || fsType === "veryfront-api";
|
|
142
|
-
const baseDir = useRelativePaths ? tasksDir : join(projectDir, tasksDir);
|
|
154
|
+
const baseDir = resolveTasksBaseDir(projectDir, tasksDir, config);
|
|
143
155
|
try {
|
|
144
156
|
const dirExists = await adapter.fs.exists(baseDir);
|
|
145
157
|
if (!dirExists)
|
|
146
158
|
return null;
|
|
147
|
-
const files = await
|
|
148
|
-
baseDir,
|
|
149
|
-
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
150
|
-
recursive: true,
|
|
151
|
-
ignorePatterns: ["node_modules", ".git", "__tests__", "*.test.*", "*.spec.*"],
|
|
152
|
-
adapter,
|
|
153
|
-
});
|
|
159
|
+
const files = await collectTaskFiles(baseDir, adapter);
|
|
154
160
|
for (const file of files) {
|
|
155
161
|
const id = deriveTaskId(file.path, baseDir);
|
|
156
162
|
if (id !== taskId)
|
|
157
163
|
continue;
|
|
158
164
|
try {
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const defaultExport = module.default;
|
|
164
|
-
if (isTaskDefinition(defaultExport)) {
|
|
165
|
-
if (debug) {
|
|
166
|
-
logger.info(`Found task "${id}" in ${file.path} (export: default)`);
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
id,
|
|
170
|
-
name: defaultExport.name || id,
|
|
171
|
-
filePath: file.path,
|
|
172
|
-
exportName: "default",
|
|
173
|
-
definition: defaultExport,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
for (const [exportName, value] of Object.entries(module)) {
|
|
177
|
-
if (exportName === "default")
|
|
178
|
-
continue;
|
|
179
|
-
if (isTaskDefinition(value)) {
|
|
180
|
-
if (debug) {
|
|
181
|
-
logger.info(`Found task "${id}" in ${file.path} (export: ${exportName})`);
|
|
182
|
-
}
|
|
183
|
-
return {
|
|
184
|
-
id,
|
|
185
|
-
name: value.name || id,
|
|
186
|
-
filePath: file.path,
|
|
187
|
-
exportName,
|
|
188
|
-
definition: value,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
165
|
+
const task = await loadTaskFromFile(file.path, id, adapter, projectDir);
|
|
166
|
+
if (task) {
|
|
167
|
+
logDiscoveredTask(task, debug);
|
|
168
|
+
return task;
|
|
191
169
|
}
|
|
192
170
|
}
|
|
193
171
|
catch (error) {
|
|
194
|
-
const errorMsg =
|
|
172
|
+
const errorMsg = toErrorMessage(error);
|
|
195
173
|
if (debug) {
|
|
196
174
|
logger.warn(`Failed to load ${file.path}: ${errorMsg}`);
|
|
197
175
|
}
|
|
@@ -199,7 +177,7 @@ export async function findTaskById(taskId, options) {
|
|
|
199
177
|
}
|
|
200
178
|
}
|
|
201
179
|
catch (error) {
|
|
202
|
-
const errorMsg =
|
|
180
|
+
const errorMsg = toErrorMessage(error);
|
|
203
181
|
logger.error(`Task discovery failed while finding "${taskId}": ${errorMsg}`);
|
|
204
182
|
}
|
|
205
183
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/src/tool/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/src/tool/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAalB"}
|
package/esm/src/tool/executor.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { toolRegistry } from "./registry.js";
|
|
2
2
|
import { createError, toError } from "../errors/veryfront-error.js";
|
|
3
3
|
export function executeTool(toolId, input, context) {
|
|
4
|
-
const
|
|
5
|
-
if (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
4
|
+
const registeredTool = toolRegistry.get(toolId);
|
|
5
|
+
if (!registeredTool) {
|
|
6
|
+
throw toError(createError({
|
|
7
|
+
type: "agent",
|
|
8
|
+
message: `Tool "${toolId}" not found`,
|
|
9
|
+
}));
|
|
10
|
+
}
|
|
11
|
+
return registeredTool.execute(input, context);
|
|
11
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/src/tool/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/src/tool/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAiIzE,wBAAgB,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EACtD,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAkCvB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACxF,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAC7C,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;KACpD,CAAC;CACH;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAwB7E"}
|
package/esm/src/tool/factory.js
CHANGED
|
@@ -15,6 +15,9 @@ function getSchemaShape(schema) {
|
|
|
15
15
|
return null;
|
|
16
16
|
return typeof shape === "function" ? shape() : shape;
|
|
17
17
|
}
|
|
18
|
+
function hasSchemaParse(schema) {
|
|
19
|
+
return typeof schema?.parse === "function";
|
|
20
|
+
}
|
|
18
21
|
function buildSchemaFromShape(shape, additionalProperties = false) {
|
|
19
22
|
const keys = Object.keys(shape);
|
|
20
23
|
const properties = Object.fromEntries(keys.map((key) => [key, { type: "string" }]));
|
|
@@ -32,14 +35,14 @@ function permissiveFallback(logPrefix, toolId, detail) {
|
|
|
32
35
|
function schemaError(toolId, message) {
|
|
33
36
|
throw toError(createError({ type: "agent", message: `Tool "${toolId}" ${message}` }));
|
|
34
37
|
}
|
|
35
|
-
function tryConvert(
|
|
38
|
+
function tryConvert(convertSchema, toolId, logPrefix, permissive, failureLabel) {
|
|
36
39
|
try {
|
|
37
|
-
return
|
|
40
|
+
return convertSchema();
|
|
38
41
|
}
|
|
39
42
|
catch (error) {
|
|
40
43
|
if (permissive)
|
|
41
44
|
return permissiveFallback(logPrefix, toolId, "Using permissive schema");
|
|
42
|
-
schemaError(toolId, `${
|
|
45
|
+
schemaError(toolId, `${failureLabel}: ${getErrorMessage(error)}`);
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
function logSchemaResult(logPrefix, toolId, method, schema) {
|
|
@@ -48,18 +51,14 @@ function logSchemaResult(logPrefix, toolId, method, schema) {
|
|
|
48
51
|
function convertSchemaToJson(schema, toolId, logPrefix, permissive = false) {
|
|
49
52
|
if (hasValidZodTypeName(schema)) {
|
|
50
53
|
const result = tryConvert(() => zodToJsonSchema(schema), toolId, logPrefix, permissive, "input schema conversion failed");
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return result;
|
|
54
|
-
}
|
|
54
|
+
logSchemaResult(logPrefix, toolId, "Pre-converted", result);
|
|
55
|
+
return result;
|
|
55
56
|
}
|
|
56
57
|
const shape = getSchemaShape(schema);
|
|
57
58
|
if (shape) {
|
|
58
59
|
const result = tryConvert(() => buildSchemaFromShape(shape, permissive), toolId, logPrefix, permissive, "schema introspection failed");
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return result;
|
|
62
|
-
}
|
|
60
|
+
logSchemaResult(logPrefix, toolId, "Introspected", result);
|
|
61
|
+
return result;
|
|
63
62
|
}
|
|
64
63
|
if (permissive)
|
|
65
64
|
return permissiveFallback(logPrefix, toolId, "Using fully dynamic schema");
|
|
@@ -79,10 +78,9 @@ export function tool(config) {
|
|
|
79
78
|
inputSchema: config.inputSchema,
|
|
80
79
|
inputSchemaJson,
|
|
81
80
|
execute: async (input, context) => {
|
|
82
|
-
|
|
83
|
-
if (typeof schema?.parse === "function") {
|
|
81
|
+
if (hasSchemaParse(config.inputSchema)) {
|
|
84
82
|
try {
|
|
85
|
-
|
|
83
|
+
config.inputSchema.parse(input);
|
|
86
84
|
}
|
|
87
85
|
catch (error) {
|
|
88
86
|
throw toError(createError({
|
|
@@ -106,8 +104,7 @@ export function dynamicTool(config) {
|
|
|
106
104
|
inputSchema: config.inputSchema,
|
|
107
105
|
inputSchemaJson,
|
|
108
106
|
execute: async (input, context) => {
|
|
109
|
-
if (config.inputSchema
|
|
110
|
-
typeof config.inputSchema.parse === "function") {
|
|
107
|
+
if (hasSchemaParse(config.inputSchema)) {
|
|
111
108
|
config.inputSchema.parse(input);
|
|
112
109
|
}
|
|
113
110
|
else if (input === undefined) {
|
|
@@ -35,6 +35,10 @@ export declare function stripSemverRange(version: string): string;
|
|
|
35
35
|
* Compatibility no-op. Kept for tests and older call sites.
|
|
36
36
|
*/
|
|
37
37
|
export declare function clearReactVersionCache(): void;
|
|
38
|
+
export declare function readProjectDependencyVersions(projectDir: string): Promise<{
|
|
39
|
+
react?: string;
|
|
40
|
+
veryfront?: string;
|
|
41
|
+
}>;
|
|
38
42
|
/**
|
|
39
43
|
* Resolve React version for a project with consistent priority:
|
|
40
44
|
* 1. Config override: config.client.cdn.versions.react
|