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
@@ -26,16 +26,20 @@ import { computeSourceHash } from "../../studio/hash-utils.js";
26
26
  import { extractRelativePath } from "../../utils/route-path-utils.js";
27
27
  import { resolveAppComponentPath } from "../layouts/utils/app-resolver.js";
28
28
  import { StreamTimeoutError, streamToString } from "../utils/stream-utils.js";
29
+ import { profilePhase, profileSyncPhase } from "../../observability/request-profiler.js";
29
30
  import {
30
31
  normalizeCssModuleKey,
31
32
  rewriteCssModuleContent,
32
33
  } from "../../transforms/css-modules/naming.js";
34
+ import { getProjectCSS } from "../../html/styles-builder/index.js";
35
+ import { warmPreparedCSSArtifactFromFiles } from "../../html/styles-builder/css-pregeneration.js";
33
36
  import { getRouteCandidates } from "./css-candidate-manifest.js";
34
37
  import { resolveStyleContentVersion } from "../../html/styles-builder/content-version.js";
35
38
  import { createStyleScopeProfile } from "../../html/styles-builder/style-scope-profile.js";
36
39
  import type { ResolvedContentContext } from "../../platform/adapters/fs/veryfront/types.js";
37
40
 
38
41
  const logger = rendererLogger.component("html-generator");
42
+ type ProjectCSSResult = Awaited<ReturnType<typeof getProjectCSS>> | null;
39
43
 
40
44
  function findTagEnd(html: string, start: number): number {
41
45
  let activeQuote: '"' | "'" | null = null;
@@ -187,7 +191,12 @@ export class HTMLGenerator {
187
191
  ): Promise<ReadableStream> {
188
192
  const fullContext = context as HTMLGenerationContext;
189
193
  const mergedFrontmatter = this.mergeFrontmatter(fullContext);
190
- const htmlOptions = await this.buildHTMLOptions(fullContext, mergedFrontmatter);
194
+ const htmlOptions = await profilePhase(
195
+ "html.build_options",
196
+ () => this.buildHTMLOptions(fullContext, mergedFrontmatter),
197
+ );
198
+ const projectCSSPromise = this.startProjectCSSPreparation(fullContext, htmlOptions);
199
+ this.startPreparedCSSWarmup(fullContext, htmlOptions);
191
200
 
192
201
  let reactContent: string;
193
202
  try {
@@ -201,11 +210,16 @@ export class HTMLGenerator {
201
210
  reactContent = error.partialContent.trim();
202
211
  }
203
212
 
204
- const { start, end } = await this.generateShellParts(
205
- fullContext,
206
- mergedFrontmatter,
207
- htmlOptions,
208
- reactContent,
213
+ const { start, end } = await profilePhase(
214
+ "html.generate_shell_parts",
215
+ () =>
216
+ this.generateShellParts(
217
+ fullContext,
218
+ mergedFrontmatter,
219
+ htmlOptions,
220
+ reactContent,
221
+ projectCSSPromise,
222
+ ),
209
223
  );
210
224
 
211
225
  const encoder = new TextEncoder();
@@ -276,14 +290,24 @@ export class HTMLGenerator {
276
290
 
277
291
  private async wrapHTMLFragment(context: HTMLGenerationContext): Promise<string> {
278
292
  const mergedFrontmatter = this.mergeFrontmatter(context);
279
- const htmlOptions = await this.buildHTMLOptions(context, mergedFrontmatter);
293
+ const htmlOptions = await profilePhase(
294
+ "html.build_options",
295
+ () => this.buildHTMLOptions(context, mergedFrontmatter),
296
+ );
297
+ const projectCSSPromise = this.startProjectCSSPreparation(context, htmlOptions);
298
+ this.startPreparedCSSWarmup(context, htmlOptions);
280
299
  const reactContent = context.html.trim();
281
300
 
282
- const { start, end } = await this.generateShellParts(
283
- context,
284
- mergedFrontmatter,
285
- htmlOptions,
286
- reactContent,
301
+ const { start, end } = await profilePhase(
302
+ "html.generate_shell_parts",
303
+ () =>
304
+ this.generateShellParts(
305
+ context,
306
+ mergedFrontmatter,
307
+ htmlOptions,
308
+ reactContent,
309
+ projectCSSPromise,
310
+ ),
287
311
  );
288
312
 
289
313
  return `${start}${reactContent}${end}`;
@@ -294,6 +318,7 @@ export class HTMLGenerator {
294
318
  mergedFrontmatter: MDXFrontmatter,
295
319
  htmlOptions: HTMLGenerationOptions,
296
320
  reactContent: string,
321
+ projectCSSPromise?: Promise<ProjectCSSResult>,
297
322
  ): Promise<{ start: string; end: string }> {
298
323
  const head = context.collectedHead;
299
324
  const effectiveTitle = head?.title || mergedFrontmatter.title || "Veryfront App";
@@ -317,6 +342,7 @@ export class HTMLGenerator {
317
342
  context.options?.params,
318
343
  context.options?.props,
319
344
  reactContent,
345
+ projectCSSPromise,
320
346
  );
321
347
 
322
348
  const { scripts, other } = this.buildHeadElements(head);
@@ -343,6 +369,76 @@ export class HTMLGenerator {
343
369
  return { start: modifiedStart, end };
344
370
  }
345
371
 
372
+ private startProjectCSSPreparation(
373
+ context: HTMLGenerationContext,
374
+ htmlOptions: HTMLGenerationOptions,
375
+ ): Promise<ProjectCSSResult> | undefined {
376
+ const isLocalProject = htmlOptions.isLocalProject ?? false;
377
+ if (isLocalProject || htmlOptions.environment !== "production") return undefined;
378
+
379
+ const projectScope = htmlOptions.projectSlug || htmlOptions.projectId || context.slug;
380
+ if (!projectScope || projectScope === "default") return undefined;
381
+
382
+ return getProjectCSS(
383
+ projectScope,
384
+ htmlOptions.globalCSS,
385
+ new Set([...(htmlOptions.projectClasses ?? [])]),
386
+ {
387
+ minify: true,
388
+ environment: htmlOptions.environment,
389
+ buildMode: htmlOptions.mode,
390
+ },
391
+ );
392
+ }
393
+
394
+ private startPreparedCSSWarmup(
395
+ context: HTMLGenerationContext,
396
+ htmlOptions: HTMLGenerationOptions,
397
+ ): void {
398
+ const isLocalProject = htmlOptions.isLocalProject ?? false;
399
+ const usesPreviewStylesheet = isLocalProject || htmlOptions.environment !== "production";
400
+ if (!usesPreviewStylesheet) return;
401
+
402
+ const wrappedFs = this.config.adapter.fs as unknown as {
403
+ getUnderlyingAdapter?: () => unknown;
404
+ };
405
+ if (typeof wrappedFs.getUnderlyingAdapter !== "function") return;
406
+
407
+ const fsAdapter = wrappedFs.getUnderlyingAdapter() as {
408
+ getAllSourceFiles?: () =>
409
+ | Array<{ path: string; content?: string }>
410
+ | Promise<Array<{ path: string; content?: string }>>;
411
+ };
412
+ if (typeof fsAdapter.getAllSourceFiles !== "function") return;
413
+
414
+ const projectScope = htmlOptions.projectSlug || htmlOptions.projectId || context.slug;
415
+ if (!projectScope || projectScope === "default") return;
416
+
417
+ const projectVersion = this.getProjectContentVersion() ??
418
+ (this.config.mode === "development" ? "dev" : "unknown");
419
+ const styleProfile = createStyleScopeProfile(this.config.config);
420
+ const stylesheetPath = this.config.config?.tailwind?.stylesheet;
421
+
422
+ Promise.resolve(fsAdapter.getAllSourceFiles()).then((files) =>
423
+ warmPreparedCSSArtifactFromFiles({
424
+ projectSlug: projectScope,
425
+ projectVersion,
426
+ projectDir: this.config.projectDir,
427
+ files,
428
+ styleProfile,
429
+ stylesheetPath,
430
+ minify: true,
431
+ environment: "preview",
432
+ buildMode: "production",
433
+ })
434
+ ).catch((error) => {
435
+ logger.debug("Prepared CSS warmup skipped after source scan failure", {
436
+ projectScope,
437
+ error: error instanceof Error ? error.message : String(error),
438
+ });
439
+ });
440
+ }
441
+
346
442
  private buildHeadElements(head?: CollectedHead): { scripts: string; other: string } {
347
443
  if (!head) return { scripts: "", other: "" };
348
444
 
@@ -438,15 +534,21 @@ export class HTMLGenerator {
438
534
  ): Promise<HTMLGenerationOptions> {
439
535
  const stylesheetPath = this.config.config?.tailwind?.stylesheet || "globals.css";
440
536
  const [appComponentPathOrNull, globalCSS] = await Promise.all([
441
- this.resolveAppPath(),
442
- this.loadProjectFile(stylesheetPath),
537
+ profilePhase("html.resolve_app_path", () => this.resolveAppPath()),
538
+ profilePhase("html.load_global_css", () => this.loadProjectFile(stylesheetPath)),
443
539
  ]);
444
540
  const appComponentPath = appComponentPathOrNull ?? undefined;
445
- const projectClasses = await this.extractProjectClassesForRoute(context, appComponentPath);
541
+ const projectClasses = await profilePhase(
542
+ "html.route_candidates",
543
+ () => this.extractProjectClassesForRoute(context, appComponentPath),
544
+ );
446
545
 
447
546
  // Load CSS imported by components and merge with globalCSS.
448
547
  // Deduplicate against the configured stylesheet to avoid double-loading.
449
- const combinedCSS = await this.mergeImportedCSS(globalCSS, context.cssImports, stylesheetPath);
548
+ const combinedCSS = await profilePhase(
549
+ "html.merge_imported_css",
550
+ () => this.mergeImportedCSS(globalCSS, context.cssImports, stylesheetPath),
551
+ );
450
552
 
451
553
  logger.debug("App component resolution", {
452
554
  appComponentPath,
@@ -474,7 +576,7 @@ export class HTMLGenerator {
474
576
  ? computeSourceHash(context.pageInfo.entity.content)
475
577
  : undefined;
476
578
 
477
- return {
579
+ return profileSyncPhase("html.build_options.finalize", () => ({
478
580
  mode: this.config.mode,
479
581
  config: this.config.config,
480
582
  projectDir: this.config.projectDir,
@@ -491,6 +593,7 @@ export class HTMLGenerator {
491
593
  frontmatter: mergedFrontmatter,
492
594
  studioEmbed: context.options?.studioEmbed,
493
595
  projectId: context.options?.projectId,
596
+ projectSlug: context.options?.projectSlug,
494
597
  pageId: context.options?.pageId,
495
598
  sourceHash,
496
599
  colorScheme: context.options?.colorScheme,
@@ -501,7 +604,8 @@ export class HTMLGenerator {
501
604
  projectClasses,
502
605
  isLocalProject: this.config.mode === "development",
503
606
  noHmr: context.options?.noHmr,
504
- };
607
+ forceProductionScripts: context.options?.forceProductionScripts,
608
+ }));
505
609
  }
506
610
 
507
611
  /**
@@ -12,6 +12,10 @@ import type { RenderOptions } from "./types.js";
12
12
  import { runWithHeadCollector } from "../../react/head-collector.js";
13
13
  import { getWorkerPool, isSSRIsolationEnabled } from "../../security/sandbox/worker-pool.js";
14
14
  import type { WorkerResponse } from "../../security/sandbox/worker-types.js";
15
+ import {
16
+ endRenderSession,
17
+ hasRenderSession,
18
+ } from "../../transforms/mdx/esm-module-loader/module-fetcher/index.js";
15
19
 
16
20
  const logger = rendererLogger.component("ssr-orchestrator");
17
21
 
@@ -113,6 +117,10 @@ export class SSROrchestrator {
113
117
 
114
118
  const { html, stream } = renderResult;
115
119
 
120
+ if (options?.renderSessionId && hasRenderSession(options.renderSessionId)) {
121
+ endRenderSession(options.renderSessionId);
122
+ }
123
+
116
124
  const mergedOptions = {
117
125
  ...generationContext.options,
118
126
  ...options,
@@ -55,6 +55,10 @@ export interface RenderOptions {
55
55
  skipCachePersist?: boolean;
56
56
  /** Disable HMR scripts (for embedded iframes where WebSocket is unwanted) */
57
57
  noHmr?: boolean;
58
+ /** Force production client scripts even when rendering a local project */
59
+ forceProductionScripts?: boolean;
60
+ /** Internal SSR module-tracking session id for first-response manifest preloads */
61
+ renderSessionId?: string;
58
62
  }
59
63
 
60
64
  export interface RenderContext {
@@ -1,9 +1,5 @@
1
1
  import type { DirEntry, FileInfo } from "../platform/adapters/base.js";
2
-
3
- // Re-export schema-based types
4
2
  export type { CacheRepositoryOptions, CacheStats, RepositoryContext } from "./schemas/index.js";
5
-
6
- // Import for use in interface definitions
7
3
  import type { CacheStats, RepositoryContext } from "./schemas/index.js";
8
4
 
9
5
  export interface FileSystemRepository {
@@ -12,8 +12,8 @@ import { createError, toError } from "../errors/veryfront-error.js";
12
12
  export function resource<TParams = unknown, TData = unknown>(
13
13
  config: ResourceConfig<TParams, TData>,
14
14
  ): Resource<TParams, TData> {
15
- const pattern = config.pattern ?? generateResourcePattern();
16
- const id = patternToId(pattern);
15
+ const pattern = config.pattern ?? generateFallbackPattern();
16
+ const id = resourcePatternToId(pattern);
17
17
 
18
18
  return {
19
19
  id,
@@ -24,13 +24,7 @@ export function resource<TParams = unknown, TData = unknown>(
24
24
  try {
25
25
  config.paramsSchema.parse(params);
26
26
  } catch (error) {
27
- const message = error instanceof Error ? error.message : String(error);
28
- throw toError(
29
- createError({
30
- type: "agent",
31
- message: `Resource "${id}" params validation failed: ${message}`,
32
- }),
33
- );
27
+ throw createParamsValidationError(id, error);
34
28
  }
35
29
 
36
30
  return config.load(params);
@@ -46,7 +40,7 @@ export function resource<TParams = unknown, TData = unknown>(
46
40
  * Auto-discovery is handled by the discovery module which scans
47
41
  * the filesystem and extracts patterns from resource definitions.
48
42
  */
49
- function generateResourcePattern(): string {
43
+ function generateFallbackPattern(): string {
50
44
  return `/resource_${Date.now()}`;
51
45
  }
52
46
 
@@ -54,6 +48,16 @@ function generateResourcePattern(): string {
54
48
  * Convert path pattern to ID
55
49
  * Example: "/users/:userId/profile" -> "users_userId_profile"
56
50
  */
57
- function patternToId(pattern: string): string {
51
+ function resourcePatternToId(pattern: string): string {
58
52
  return pattern.replace(/^\//, "").replace(/\//g, "_").replace(/:/g, "");
59
53
  }
54
+
55
+ function createParamsValidationError(resourceId: string, cause: unknown): Error {
56
+ const message = cause instanceof Error ? cause.message : String(cause);
57
+ return toError(
58
+ createError({
59
+ type: "agent",
60
+ message: `Resource "${resourceId}" params validation failed: ${message}`,
61
+ }),
62
+ );
63
+ }
@@ -11,12 +11,12 @@ import type { Resource } from "./types.js";
11
11
  import { ProjectScopedRegistryManager } from "../ai/registry-manager.js";
12
12
  import { ScopedRegistryFacade } from "../ai/registry-facade.js";
13
13
 
14
- const resourceManager = new ProjectScopedRegistryManager<Resource>("resource");
14
+ const resourceRegistryManager = new ProjectScopedRegistryManager<Resource>("resource");
15
15
 
16
- class ResourceRegistryClass extends ScopedRegistryFacade<Resource> {
16
+ class ResourceRegistry extends ScopedRegistryFacade<Resource> {
17
17
  findByPattern(uri: string): Resource | undefined {
18
18
  for (const resource of this.getAll().values()) {
19
- if (this.matchesPattern(uri, resource.pattern)) return resource;
19
+ if (this.matchPattern(uri, resource.pattern)) return resource;
20
20
  }
21
21
  return undefined;
22
22
  }
@@ -25,12 +25,12 @@ class ResourceRegistryClass extends ScopedRegistryFacade<Resource> {
25
25
  return new RegExp(`^${pattern.replace(/:(\w+)/g, "(?<$1>[^/]+)")}$`);
26
26
  }
27
27
 
28
- private matchesPattern(uri: string, pattern: string): boolean {
29
- return this.patternToRegex(pattern).test(uri);
28
+ private matchPattern(uri: string, pattern: string): RegExpMatchArray | null {
29
+ return uri.match(this.patternToRegex(pattern));
30
30
  }
31
31
 
32
32
  extractParams(uri: string, pattern: string): Record<string, string> {
33
- return uri.match(this.patternToRegex(pattern))?.groups ?? {};
33
+ return this.matchPattern(uri, pattern)?.groups ?? {};
34
34
  }
35
35
 
36
36
  list(): string[] {
@@ -38,4 +38,4 @@ class ResourceRegistryClass extends ScopedRegistryFacade<Resource> {
38
38
  }
39
39
  }
40
40
 
41
- export const resourceRegistry = new ResourceRegistryClass(resourceManager);
41
+ export const resourceRegistry = new ResourceRegistry(resourceRegistryManager);
@@ -1,12 +1,16 @@
1
1
  import { z } from "zod";
2
2
  import { MAX_URL_LENGTH_FOR_VALIDATION } from "../utils/constants/index.js";
3
+ import { timestamp } from "./primitives.js";
4
+
5
+ const SLUG_PATTERN = /^[a-z0-9-]+$/;
6
+ const E164_PHONE_NUMBER_PATTERN = /^\+?[1-9]\d{1,14}$/;
3
7
 
4
8
  export const CommonSchemas = {
5
9
  email: z.string().email().max(255),
6
10
  uuid: z.string().uuid(),
7
- slug: z.string().regex(/^[a-z0-9-]+$/).min(1).max(100),
11
+ slug: z.string().regex(SLUG_PATTERN).min(1).max(100),
8
12
  url: z.string().url().max(MAX_URL_LENGTH_FOR_VALIDATION),
9
- phoneNumber: z.string().regex(/^\+?[1-9]\d{1,14}$/),
13
+ phoneNumber: z.string().regex(E164_PHONE_NUMBER_PATTERN),
10
14
 
11
15
  pagination: z.object({
12
16
  page: z.coerce.number().int().positive().default(1),
@@ -17,8 +21,8 @@ export const CommonSchemas = {
17
21
 
18
22
  dateRange: z
19
23
  .object({
20
- from: z.string().datetime(),
21
- to: z.string().datetime(),
24
+ from: timestamp,
25
+ to: timestamp,
22
26
  })
23
27
  .refine(({ from, to }) => new Date(from) <= new Date(to), {
24
28
  message: "From date must be before or equal to To date",
@@ -33,7 +37,6 @@ export const CommonSchemas = {
33
37
  .regex(/[^A-Za-z0-9]/, "Password must contain at least one special character"),
34
38
  };
35
39
 
36
- // Export inferred types for convenience
37
40
  export type Email = z.infer<typeof CommonSchemas.email>;
38
41
  export type Uuid = z.infer<typeof CommonSchemas.uuid>;
39
42
  export type Slug = z.infer<typeof CommonSchemas.slug>;
@@ -3,7 +3,7 @@ import type { SecurityConfig } from "../../types/index.js";
3
3
  import type { VeryfrontConfig } from "../../config/index.js";
4
4
  import { getConfig } from "../../config/index.js";
5
5
  import { serverLogger } from "../../utils/index.js";
6
- import { buildCSP, generateNonce } from "./response/security-handler.js";
6
+ import { buildCSP, generateNonce, serializeCSPDirectives } from "./response/security-handler.js";
7
7
 
8
8
  const logger = serverLogger.component("security-config-loader");
9
9
 
@@ -33,7 +33,7 @@ export class SecurityConfigLoader {
33
33
  this.applyConfig(cfg);
34
34
  } catch (error) {
35
35
  // Config is optional, so we don't throw
36
- logger.debug("Failed to load config:", error);
36
+ logger.debug("Failed to load config", { error });
37
37
  this.isLoaded = true; // Mark as loaded even on error to prevent retry
38
38
  }
39
39
  }
@@ -54,26 +54,10 @@ export class SecurityConfigLoader {
54
54
  }
55
55
 
56
56
  this.securityConfig = security;
57
- this.cspUserHeader = this.parseCspUserHeader(security.csp);
57
+ this.cspUserHeader = serializeCSPDirectives(security.csp);
58
58
  this.isLoaded = true;
59
59
  }
60
60
 
61
- private parseCspUserHeader(csp: SecurityConfig["csp"]): string | null {
62
- if (!csp || typeof csp !== "object") return null;
63
-
64
- const pieces: string[] = [];
65
-
66
- for (const [k, v] of Object.entries(csp)) {
67
- if (v === undefined) continue;
68
-
69
- const key = k.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
70
- const val = Array.isArray(v) ? v.join(" ") : String(v);
71
- pieces.push(`${key} ${val}`);
72
- }
73
-
74
- return pieces.length ? pieces.join("; ") : null;
75
- }
76
-
77
61
  getSecurityConfig(): SecurityConfig | null {
78
62
  return this.securityConfig;
79
63
  }
@@ -56,6 +56,26 @@ function buildDefaultCSP(nonce: string): string {
56
56
  ].join("; ");
57
57
  }
58
58
 
59
+ export function serializeCSPDirectives(
60
+ csp: SecurityConfig["csp"],
61
+ nonce?: string,
62
+ ): string | null {
63
+ if (!csp || typeof csp !== "object") return null;
64
+
65
+ const pieces: string[] = [];
66
+
67
+ for (const [key, value] of Object.entries(csp)) {
68
+ if (value === undefined) continue;
69
+
70
+ const directive = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
71
+ const sources = Array.isArray(value) ? value.join(" ") : String(value);
72
+ const serialized = `${directive} ${sources}`;
73
+ pieces.push(nonce ? serialized.replace(/{NONCE}/g, nonce) : serialized);
74
+ }
75
+
76
+ return pieces.length ? pieces.join("; ") : null;
77
+ }
78
+
59
79
  export function buildCSP(
60
80
  isDev: boolean,
61
81
  nonce: string,
@@ -69,19 +89,8 @@ export function buildCSP(
69
89
  if (cspUserHeader?.trim()) return cspUserHeader.replace(/{NONCE}/g, nonce);
70
90
 
71
91
  const cfgCsp = config?.csp;
72
- if (cfgCsp && typeof cfgCsp === "object") {
73
- const pieces: string[] = [];
74
-
75
- for (const [k, v] of Object.entries(cfgCsp)) {
76
- if (v === undefined) continue;
77
-
78
- const key = k.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
79
- const val = Array.isArray(v) ? v.join(" ") : String(v);
80
- pieces.push(`${key} ${val}`.replace(/{NONCE}/g, nonce));
81
- }
82
-
83
- if (pieces.length) return pieces.join("; ");
84
- }
92
+ const serializedConfigCsp = serializeCSPDirectives(cfgCsp, nonce);
93
+ if (serializedConfigCsp) return serializedConfigCsp;
85
94
 
86
95
  // No explicit CSP configured — apply a secure default in production.
87
96
  // Dev mode skips the default to avoid blocking HMR and dev tooling.
@@ -30,13 +30,10 @@ export type {
30
30
  ValidatedHandlerFunction,
31
31
  } from "./input-validation/index.js";
32
32
 
33
- export {
34
- AuthHandler,
35
- loadSecurityConfig,
36
- SecurityConfigLoader,
37
- setCors,
38
- } from "./http/handlers-index.js";
39
- export type { CORSConfig, CSPDirectives, SecurityConfig } from "./http/handlers-index.js";
33
+ export { AuthHandler } from "./http/auth.js";
34
+ export { SecurityConfigLoader } from "./http/config.js";
35
+ export { loadSecurityConfig, setCors } from "./http/middleware/index.js";
36
+ export type { CORSConfig, CSPDirectives, SecurityConfig } from "./http/middleware/index.js";
40
37
 
41
38
  export { CsrfHandler } from "./http/csrf/index.js";
42
39
  export { applyCsrfCookie, generateCsrfToken, validateCsrf } from "./csrf/index.js";
@@ -34,6 +34,7 @@ import type {
34
34
  VeryfrontApiClient,
35
35
  } from "../../../platform/adapters/veryfront-api-client/index.js";
36
36
  import { extractProjectCandidates } from "./styles-candidate-scanner.js";
37
+ import { profilePhase } from "../../../observability/request-profiler.js";
37
38
 
38
39
  const logger = serverLogger.component("styles-css-handler");
39
40
 
@@ -59,7 +60,7 @@ export class StylesCSSHandler extends BaseHandler {
59
60
  const contentContext = this.getContentContext(ctx);
60
61
  let rawCss: string;
61
62
  try {
62
- rawCss = await this.loadStylesheet(ctx);
63
+ rawCss = await profilePhase("css.load_stylesheet", () => this.loadStylesheet(ctx));
63
64
  } catch (error) {
64
65
  logger.error("Failed to load stylesheet", {
65
66
  error: error instanceof Error ? error.message : String(error),
@@ -75,7 +76,10 @@ export class StylesCSSHandler extends BaseHandler {
75
76
  );
76
77
 
77
78
  if (preparedContext) {
78
- const prepared = await tryGetPreparedProjectCSS(preparedContext);
79
+ const prepared = await profilePhase(
80
+ "css.prepared_cache_lookup",
81
+ () => tryGetPreparedProjectCSS(preparedContext),
82
+ );
79
83
  if (prepared) {
80
84
  logger.debug("Prepared CSS cache hit", {
81
85
  projectScope,
@@ -90,12 +94,16 @@ export class StylesCSSHandler extends BaseHandler {
90
94
  }
91
95
  }
92
96
 
93
- const remotePrepared = await this.tryResolveRemotePreparedCSS(
94
- ctx,
95
- projectScope,
96
- styleProfile.hash,
97
- contentContext,
98
- preparedContext,
97
+ const remotePrepared = await profilePhase(
98
+ "css.remote_artifact_lookup",
99
+ () =>
100
+ this.tryResolveRemotePreparedCSS(
101
+ ctx,
102
+ projectScope,
103
+ styleProfile.hash,
104
+ contentContext,
105
+ preparedContext,
106
+ ),
99
107
  );
100
108
  if (remotePrepared) {
101
109
  logger.debug("Prepared CSS resolved via style artifact metadata", {
@@ -111,7 +119,10 @@ export class StylesCSSHandler extends BaseHandler {
111
119
 
112
120
  let candidates: Set<string>;
113
121
  try {
114
- candidates = await extractProjectCandidates(ctx);
122
+ candidates = await profilePhase(
123
+ "css.extract_candidates",
124
+ () => extractProjectCandidates(ctx),
125
+ );
115
126
  } catch (error) {
116
127
  logger.error("Failed to extract candidates", {
117
128
  error: error instanceof Error ? error.message : String(error),
@@ -120,7 +131,10 @@ export class StylesCSSHandler extends BaseHandler {
120
131
  }
121
132
  let result: GeneratedStylesResult;
122
133
  try {
123
- result = await this.generateStylesheet(ctx, rawCss, candidates);
134
+ result = await profilePhase(
135
+ "css.generate_stylesheet",
136
+ () => this.generateStylesheet(ctx, rawCss, candidates),
137
+ );
124
138
  } catch (error) {
125
139
  const formatted = formatCSSError(error instanceof Error ? error : String(error));
126
140
  logger.error("Tailwind error", {
@@ -173,10 +187,14 @@ body::before {
173
187
  });
174
188
 
175
189
  if (preparedContext && "hash" in result) {
176
- await storePreparedProjectCSS(preparedContext, {
177
- css: result.css,
178
- hash: result.hash,
179
- });
190
+ await profilePhase(
191
+ "css.store_prepared",
192
+ () =>
193
+ storePreparedProjectCSS(preparedContext, {
194
+ css: result.css,
195
+ hash: result.hash,
196
+ }),
197
+ );
180
198
  }
181
199
 
182
200
  if ("hash" in result) {
@@ -2,6 +2,7 @@ import * as dntShim from "../../../../_dnt.shims.js";
2
2
  import { BaseHandler } from "../response/base.js";
3
3
  import type { HandlerContext, HandlerMetadata, HandlerPriority, HandlerResult } from "../types.js";
4
4
  import { metrics } from "../../../observability/simple-metrics/index.js";
5
+ import { snapshotRequestProfiles } from "../../../observability/request-profiler.js";
5
6
  import { ResponseBuilder } from "../../../security/index.js";
6
7
  import {
7
8
  HTTP_INTERNAL_SERVER_ERROR,
@@ -29,11 +30,12 @@ export class MetricsHandler extends BaseHandler {
29
30
 
30
31
  try {
31
32
  const snap = metrics.snapshot();
33
+ const profiling = snapshotRequestProfiles();
32
34
  const memory = this.safeCall(memoryUsage);
33
35
  const uptimeValue = this.safeCall(uptime);
34
36
 
35
37
  const response = ResponseBuilder.json(
36
- { counters: snap, memory, uptime: uptimeValue },
38
+ { counters: snap, profiling, memory, uptime: uptimeValue },
37
39
  req,
38
40
  { securityConfig, corsConfig, status: HTTP_OK },
39
41
  );