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