@vfrey/vfrey 0.0.1 → 1.0.0-beta.0

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 (603) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +78 -3
  3. package/accounts.example.json +61 -0
  4. package/accounts.first-run.json +41 -0
  5. package/bin/vfrey.mjs +36 -0
  6. package/integration-tools/README.md +43 -0
  7. package/integration-tools/image/pillow.md +32 -0
  8. package/integration-tools/image/playwright.md +33 -0
  9. package/integration-tools/image/resvg.md +36 -0
  10. package/integration-tools/image/satori.md +36 -0
  11. package/integration-tools/image/sharp.md +38 -0
  12. package/integration-tools/video/blender.md +34 -0
  13. package/integration-tools/video/ffmpeg.md +41 -0
  14. package/integration-tools/video/manim.md +37 -0
  15. package/integration-tools/video/motion-canvas.md +37 -0
  16. package/integration-tools/video/remotion.md +50 -0
  17. package/integration-tools/video/revideo.md +32 -0
  18. package/package.json +74 -6
  19. package/skills/vfrey-orchestrator/SKILL.md +15 -0
  20. package/skills/vfrey-orchestrator/channel-video/SKILL.md +41 -0
  21. package/skills/vfrey-product/SKILL.md +63 -0
  22. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-one.svg +14 -0
  23. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-two.svg +22 -0
  24. package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/index.html +70 -0
  25. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-one.svg +14 -0
  26. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-two.svg +22 -0
  27. package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/index.tsx +49 -0
  28. package/skills/vfrey-product/examples/concurrency-vs-parallelism/script.json +15 -0
  29. package/skills/vfrey-product/examples/octopus-facts/index.html +60 -0
  30. package/skills/vfrey-product/examples/octopus-facts/octopus.svg +8 -0
  31. package/skills/vfrey-product/examples/octopus-facts/script.json +14 -0
  32. package/skills/vfrey-product/push/SKILL.md +15 -0
  33. package/skills/vfrey-product/scenes/NOTICE +5 -0
  34. package/skills/vfrey-product/scenes/blocks.md +57 -0
  35. package/skills/vfrey-product/scenes/craft.md +118 -0
  36. package/skills/vfrey-product/scenes/motion.md +88 -0
  37. package/src/analytics/dashboard.ts +109 -0
  38. package/src/analytics/index.ts +260 -0
  39. package/src/api/client.ts +282 -0
  40. package/src/api/commands.ts +330 -0
  41. package/src/api/config.ts +34 -0
  42. package/src/api/creators.ts +463 -0
  43. package/src/api/credentials.ts +152 -0
  44. package/src/api/mail.ts +333 -0
  45. package/src/api/topics.ts +207 -0
  46. package/src/api/types.ts +205 -0
  47. package/src/cli.ts +467 -0
  48. package/src/cloud/executor.ts +281 -0
  49. package/src/cloud/job.ts +106 -0
  50. package/src/cloud/render-job.ts +187 -0
  51. package/src/config.ts +309 -0
  52. package/src/dashboard-link.ts +180 -0
  53. package/src/dashboard-start.ts +103 -0
  54. package/src/desk/channel.ts +64 -0
  55. package/src/desk/cli.ts +216 -0
  56. package/src/desk/creators-route.ts +129 -0
  57. package/src/desk/fonts/JetBrainsMono-OFL.txt +93 -0
  58. package/src/desk/fonts/google-sans-flex-latin.woff2 +0 -0
  59. package/src/desk/fonts/jetbrains-mono-medium.woff2 +0 -0
  60. package/src/desk/http.ts +460 -0
  61. package/src/desk/mail-route.ts +103 -0
  62. package/src/desk/overlay.ts +112 -0
  63. package/src/desk/preview.ts +422 -0
  64. package/src/desk/screens.ts +149 -0
  65. package/src/desk/secrets.ts +143 -0
  66. package/src/desk/series.ts +127 -0
  67. package/src/desk/state.ts +77 -0
  68. package/src/desk/studio-route.ts +119 -0
  69. package/src/desk/tick-runner.ts +66 -0
  70. package/src/desk/tick.ts +56 -0
  71. package/src/desk/topics-route.ts +41 -0
  72. package/src/desk/ui/app.css +505 -0
  73. package/src/desk/ui/app.js +185 -0
  74. package/src/desk/ui/apple-icon.png +0 -0
  75. package/src/desk/ui/components.js +79 -0
  76. package/src/desk/ui/core.js +156 -0
  77. package/src/desk/ui/favicon.ico +0 -0
  78. package/src/desk/ui/icon.svg +1 -0
  79. package/src/desk/ui/icons.js +49 -0
  80. package/src/desk/ui/index.html +41 -0
  81. package/src/desk/ui/metrics-math.d.ts +22 -0
  82. package/src/desk/ui/metrics-math.js +135 -0
  83. package/src/desk/ui/theme.js +5 -0
  84. package/src/desk/ui/views-creators.js +209 -0
  85. package/src/desk/ui/views-keys.js +114 -0
  86. package/src/desk/ui/views-mail.js +188 -0
  87. package/src/desk/ui/views-misc.js +123 -0
  88. package/src/desk/ui/views-review.js +119 -0
  89. package/src/desk/ui/views-runs.js +350 -0
  90. package/src/desk/ui/views-screens.js +163 -0
  91. package/src/desk/ui/views-series.js +318 -0
  92. package/src/desk/ui/views-topics.js +87 -0
  93. package/src/desk/verbs.ts +361 -0
  94. package/src/doctor.ts +212 -0
  95. package/src/drain.ts +14 -0
  96. package/src/engage/index.ts +217 -0
  97. package/src/generate/index.ts +110 -0
  98. package/src/generate/script.ts +152 -0
  99. package/src/generate/title.ts +78 -0
  100. package/src/help.ts +233 -0
  101. package/src/home.ts +45 -0
  102. package/src/llm/client.ts +177 -0
  103. package/src/log.ts +7 -0
  104. package/src/oauth/tokens.ts +189 -0
  105. package/src/oauth/vault.ts +72 -0
  106. package/src/pipeline/review.ts +642 -0
  107. package/src/pipeline/run.ts +443 -0
  108. package/src/pipeline/series-guard.ts +26 -0
  109. package/src/pipeline/source-fetch.ts +69 -0
  110. package/src/pipeline/stages.ts +728 -0
  111. package/src/pipeline/topics-source.ts +90 -0
  112. package/src/product/commands.ts +296 -0
  113. package/src/product/config-file.ts +38 -0
  114. package/src/product/engine-choice.ts +89 -0
  115. package/src/product/engines.ts +103 -0
  116. package/src/product/insights.ts +50 -0
  117. package/src/product/keys.ts +67 -0
  118. package/src/product/paths.ts +18 -0
  119. package/src/product/probes.ts +88 -0
  120. package/src/product/push-flow.ts +90 -0
  121. package/src/product/render-video.ts +21 -0
  122. package/src/product/short.ts +62 -0
  123. package/src/product/update.ts +32 -0
  124. package/src/project/canonical.ts +14 -0
  125. package/src/project/commands.ts +177 -0
  126. package/src/project/dashboard-status.ts +28 -0
  127. package/src/project/discover.ts +19 -0
  128. package/src/project/index-file.ts +73 -0
  129. package/src/project/marker.ts +87 -0
  130. package/src/project/migrate.ts +201 -0
  131. package/src/project/names.ts +27 -0
  132. package/src/project/notice.ts +16 -0
  133. package/src/project/open.ts +88 -0
  134. package/src/project/scaffold.ts +112 -0
  135. package/src/project/templates.ts +42 -0
  136. package/src/project/videos.ts +64 -0
  137. package/src/publish/facebook.ts +91 -0
  138. package/src/publish/index.ts +12 -0
  139. package/src/publish/instagram.ts +97 -0
  140. package/src/publish/rate.ts +62 -0
  141. package/src/publish/session.ts +242 -0
  142. package/src/publish/tiktok.ts +202 -0
  143. package/src/publish/youtube.ts +177 -0
  144. package/src/queue/desk-ops.ts +1170 -0
  145. package/src/queue/seal.ts +3 -0
  146. package/src/queue/store.ts +1006 -0
  147. package/src/remotion/AiLabel.tsx +26 -0
  148. package/src/remotion/Root.tsx +73 -0
  149. package/src/remotion/defaults.ts +26 -0
  150. package/src/remotion/films/claude/ClaudeFilm.tsx +1014 -0
  151. package/src/remotion/films/engine/EngineMark.tsx +17 -0
  152. package/src/remotion/films/rea/ReaShort.tsx +552 -0
  153. package/src/remotion/films/rea/drawings.tsx +907 -0
  154. package/src/remotion/films/rea/timing.ts +144 -0
  155. package/src/remotion/index.ts +4 -0
  156. package/src/remotion/templates/EditorialSplit.tsx +39 -0
  157. package/src/remotion/templates/KineticType.tsx +39 -0
  158. package/src/remotion/templates/SignalBoard.tsx +50 -0
  159. package/src/remotion/timing.ts +22 -0
  160. package/src/render/chrome.ts +78 -0
  161. package/src/render/engine-mark.ts +29 -0
  162. package/src/render/framey-template.ts +130 -0
  163. package/src/render/html-engine.ts +149 -0
  164. package/src/render/node-crypto-stub.ts +11 -0
  165. package/src/render/probe.ts +29 -0
  166. package/src/render/props.ts +17 -0
  167. package/src/render/vertical-short.ts +35 -0
  168. package/src/render/webpack.ts +33 -0
  169. package/src/render/worker.ts +65 -0
  170. package/src/scene/assets/fonts/TitanOne-OFL.txt +94 -0
  171. package/src/scene/assets/fonts/titan-one.woff2 +0 -0
  172. package/src/scene/assets/gsap/LICENSE.txt +8 -0
  173. package/src/scene/assets/gsap/gsap.min.js +11 -0
  174. package/src/scene/audio.ts +54 -0
  175. package/src/scene/blocks/LICENSE +190 -0
  176. package/src/scene/blocks/NOTICE +5 -0
  177. package/src/scene/blocks/bar-chart-race/bar-chart-race.html +585 -0
  178. package/src/scene/blocks/beat-freeze-cut/beat-freeze-cut.html +874 -0
  179. package/src/scene/blocks/camcorder-hud/camcorder-hud.html +164 -0
  180. package/src/scene/blocks/camera-dolly-zoom/camera-dolly-zoom.html +355 -0
  181. package/src/scene/blocks/code-diff/code-diff.html +817 -0
  182. package/src/scene/blocks/code-snippet-apple-terminal-pro/code-snippet-apple-terminal-pro.html +248 -0
  183. package/src/scene/blocks/code-typing/code-typing.html +764 -0
  184. package/src/scene/blocks/data-chart/data-chart.html +452 -0
  185. package/src/scene/blocks/flowchart-vertical/flowchart-vertical.html +454 -0
  186. package/src/scene/blocks/hw-scribble-transition/hw-scribble-transition.html +153 -0
  187. package/src/scene/blocks/index.json +824 -0
  188. package/src/scene/blocks/lt-accent-underline/lt-accent-underline.html +107 -0
  189. package/src/scene/blocks/lt-bold-block/lt-bold-block.html +109 -0
  190. package/src/scene/blocks/lt-clean-bar/lt-clean-bar.html +112 -0
  191. package/src/scene/blocks/lt-dark-card/lt-dark-card.html +111 -0
  192. package/src/scene/blocks/lt-kicker-name/lt-kicker-name.html +114 -0
  193. package/src/scene/blocks/lt-mask-reveal/lt-mask-reveal.html +120 -0
  194. package/src/scene/blocks/lt-neon-border/lt-neon-border.html +391 -0
  195. package/src/scene/blocks/lt-stack-bars/lt-stack-bars.html +109 -0
  196. package/src/scene/blocks/macos-notification/macos-notification.html +194 -0
  197. package/src/scene/blocks/mk-background/mk-background.html +236 -0
  198. package/src/scene/blocks/mk-callout-highlight/mk-callout-highlight.html +183 -0
  199. package/src/scene/blocks/mk-clone-wall-transition/mk-clone-wall-transition.html +226 -0
  200. package/src/scene/blocks/mk-line-graph/mk-line-graph.html +293 -0
  201. package/src/scene/blocks/mk-progress-stat/mk-progress-stat.html +186 -0
  202. package/src/scene/blocks/mk-specs-list/mk-specs-list.html +223 -0
  203. package/src/scene/blocks/news-ticker/news-ticker.html +409 -0
  204. package/src/scene/blocks/organic-light-leak-overlay/organic-light-leak-overlay.html +126 -0
  205. package/src/scene/blocks/oscilloscope-trace/oscilloscope-trace.html +519 -0
  206. package/src/scene/blocks/snow/snow.html +205 -0
  207. package/src/scene/blocks/split-flap-board/split-flap-board.html +347 -0
  208. package/src/scene/blocks/spotify-card/spotify-card.html +294 -0
  209. package/src/scene/blocks/starfield/starfield.html +188 -0
  210. package/src/scene/blocks/thread-message-stack/thread-message-stack.html +239 -0
  211. package/src/scene/blocks/week-in-merges/week-in-merges.html +470 -0
  212. package/src/scene/blocks/x-post/x-post.html +437 -0
  213. package/src/scene/blocks/yt-comment-card/yt-comment-card.html +319 -0
  214. package/src/scene/blocks/yt-lcd-background/yt-lcd-background.html +307 -0
  215. package/src/scene/blocks/yt-prism-title/yt-prism-title.html +205 -0
  216. package/src/scene/blocks.ts +229 -0
  217. package/src/scene/command.ts +272 -0
  218. package/src/scene/figure.ts +181 -0
  219. package/src/scene/glyphs.ts +107 -0
  220. package/src/scene/init.ts +86 -0
  221. package/src/scene/inspect/css-tree.d.ts +6 -0
  222. package/src/scene/inspect/page-scripts.ts +272 -0
  223. package/src/scene/inspect/report.ts +405 -0
  224. package/src/scene/inspect/run.ts +200 -0
  225. package/src/scene/inspect/source.ts +236 -0
  226. package/src/scene/label.ts +131 -0
  227. package/src/scene/net-guard.ts +74 -0
  228. package/src/scene/render.ts +292 -0
  229. package/src/scene/runtime/browser.ts +199 -0
  230. package/src/scene/runtime/core.ts +181 -0
  231. package/src/scene/runtime/react.tsx +115 -0
  232. package/src/scene/runtime/transitions.ts +133 -0
  233. package/src/scene/sanitize.ts +181 -0
  234. package/src/scene/scene.ts +152 -0
  235. package/src/scene/studio-command.ts +48 -0
  236. package/src/scene/studio-skin.ts +59 -0
  237. package/src/scene/studio.ts +337 -0
  238. package/src/scene/supply.ts +111 -0
  239. package/src/scene/timing.ts +288 -0
  240. package/src/scene/transitions/LICENSE +190 -0
  241. package/src/scene/transitions/NOTICE +5 -0
  242. package/src/scene/transitions/SOURCE.json +24 -0
  243. package/src/scene/transitions/transitions.global.js +38 -0
  244. package/src/scene/transitions.ts +26 -0
  245. package/src/service/all-projects.ts +153 -0
  246. package/src/service/commands.ts +256 -0
  247. package/src/service/due.ts +82 -0
  248. package/src/service/lock.ts +101 -0
  249. package/src/service/log-file.ts +56 -0
  250. package/src/service/state.ts +41 -0
  251. package/src/service/units.ts +90 -0
  252. package/src/service/worker.ts +51 -0
  253. package/src/skill-agents.ts +74 -0
  254. package/src/skill-install.ts +334 -0
  255. package/src/sync-write.ts +21 -0
  256. package/src/tick-report.ts +205 -0
  257. package/src/tts.ts +124 -0
  258. package/vendor/@vfrey/contracts/dist/account.d.ts +97 -0
  259. package/vendor/@vfrey/contracts/dist/account.js +27 -0
  260. package/vendor/@vfrey/contracts/dist/checks.d.ts +8 -0
  261. package/vendor/@vfrey/contracts/dist/checks.js +1 -0
  262. package/vendor/@vfrey/contracts/dist/credentials/crypto.d.ts +4 -0
  263. package/vendor/@vfrey/contracts/dist/credentials/crypto.js +38 -0
  264. package/vendor/@vfrey/contracts/dist/domain/advice-persona.d.ts +10 -0
  265. package/vendor/@vfrey/contracts/dist/domain/advice-persona.js +24 -0
  266. package/vendor/@vfrey/contracts/dist/domain/backoff.d.ts +13 -0
  267. package/vendor/@vfrey/contracts/dist/domain/backoff.js +27 -0
  268. package/vendor/@vfrey/contracts/dist/domain/cadence.d.ts +29 -0
  269. package/vendor/@vfrey/contracts/dist/domain/cadence.js +95 -0
  270. package/vendor/@vfrey/contracts/dist/domain/creators.d.ts +146 -0
  271. package/vendor/@vfrey/contracts/dist/domain/creators.js +2 -0
  272. package/vendor/@vfrey/contracts/dist/domain/disclosure.d.ts +127 -0
  273. package/vendor/@vfrey/contracts/dist/domain/disclosure.js +250 -0
  274. package/vendor/@vfrey/contracts/dist/domain/errors.d.ts +34 -0
  275. package/vendor/@vfrey/contracts/dist/domain/errors.js +68 -0
  276. package/vendor/@vfrey/contracts/dist/domain/redact.d.ts +1 -0
  277. package/vendor/@vfrey/contracts/dist/domain/redact.js +21 -0
  278. package/vendor/@vfrey/contracts/dist/domain/revenue.d.ts +13 -0
  279. package/vendor/@vfrey/contracts/dist/domain/revenue.js +16 -0
  280. package/vendor/@vfrey/contracts/dist/domain/safety.d.ts +20 -0
  281. package/vendor/@vfrey/contracts/dist/domain/safety.js +61 -0
  282. package/vendor/@vfrey/contracts/dist/domain/similarity.d.ts +13 -0
  283. package/vendor/@vfrey/contracts/dist/domain/similarity.js +100 -0
  284. package/vendor/@vfrey/contracts/dist/domain/templates.d.ts +18 -0
  285. package/vendor/@vfrey/contracts/dist/domain/templates.js +67 -0
  286. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.d.ts +19 -0
  287. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.js +52 -0
  288. package/vendor/@vfrey/contracts/dist/domain/topics.d.ts +78 -0
  289. package/vendor/@vfrey/contracts/dist/domain/topics.js +4 -0
  290. package/vendor/@vfrey/contracts/dist/domain/types.d.ts +216 -0
  291. package/vendor/@vfrey/contracts/dist/domain/types.js +1 -0
  292. package/vendor/@vfrey/contracts/dist/domain/variation.d.ts +57 -0
  293. package/vendor/@vfrey/contracts/dist/domain/variation.js +278 -0
  294. package/vendor/@vfrey/contracts/dist/events.d.ts +20 -0
  295. package/vendor/@vfrey/contracts/dist/events.js +1 -0
  296. package/vendor/@vfrey/contracts/dist/http.d.ts +11 -0
  297. package/vendor/@vfrey/contracts/dist/http.js +37 -0
  298. package/vendor/@vfrey/contracts/dist/index.d.ts +22 -0
  299. package/vendor/@vfrey/contracts/dist/index.js +22 -0
  300. package/vendor/@vfrey/contracts/dist/log.d.ts +2 -0
  301. package/vendor/@vfrey/contracts/dist/log.js +10 -0
  302. package/vendor/@vfrey/contracts/dist/mail.d.ts +55 -0
  303. package/vendor/@vfrey/contracts/dist/mail.js +1 -0
  304. package/vendor/@vfrey/contracts/package.json +18 -0
  305. package/vendor/@vfrey/ingest/dist/index.d.ts +41 -0
  306. package/vendor/@vfrey/ingest/dist/index.js +221 -0
  307. package/vendor/@vfrey/ingest/dist/parse.d.ts +5 -0
  308. package/vendor/@vfrey/ingest/dist/parse.js +165 -0
  309. package/vendor/@vfrey/ingest/package.json +21 -0
  310. package/vendor/framey/LICENSE +190 -0
  311. package/vendor/framey/NOTICE +15 -0
  312. package/vendor/framey/SOURCE.json +24 -0
  313. package/vendor/framey/STUDIO-SOURCE.json +9 -0
  314. package/vendor/framey/bin/framey-localize-fonts.mjs +12 -0
  315. package/vendor/framey/bin/framey.mjs +16 -0
  316. package/vendor/framey/dist/add-VMJD5KBS.js +75 -0
  317. package/vendor/framey/dist/animatedGifPrep-QPKGJ6PM.js +43 -0
  318. package/vendor/framey/dist/api.d.ts +211 -0
  319. package/vendor/framey/dist/api.js +76 -0
  320. package/vendor/framey/dist/appHistory-WW56FZTT.js +31 -0
  321. package/vendor/framey/dist/asset-WQKGOELE.js +26 -0
  322. package/vendor/framey/dist/audio-RSJWVWRA.js +1936 -0
  323. package/vendor/framey/dist/batchRender-3HPICDCT.js +366 -0
  324. package/vendor/framey/dist/beats-HL2BDUZI.js +273 -0
  325. package/vendor/framey/dist/benchmark-RWCWHI5Z.js +230 -0
  326. package/vendor/framey/dist/browser-ECYET3Q2.js +206 -0
  327. package/vendor/framey/dist/bundleWithLocalizedFonts-ALYBQEQT.js +52 -0
  328. package/vendor/framey/dist/captureCompositionFrame-4DA6SEH2.js +94 -0
  329. package/vendor/framey/dist/catalog-5JVDEUWK.js +979 -0
  330. package/vendor/framey/dist/catch-up-NEBCL5NO.js +106 -0
  331. package/vendor/framey/dist/check-F5N544ML.js +111 -0
  332. package/vendor/framey/dist/checkBrowser-LZ66CMJG.js +110 -0
  333. package/vendor/framey/dist/chunk-2K7Z2HVP.js +372 -0
  334. package/vendor/framey/dist/chunk-2UZQHDM7.js +323 -0
  335. package/vendor/framey/dist/chunk-2X4PQEYM.js +34 -0
  336. package/vendor/framey/dist/chunk-3422KMTD.js +168 -0
  337. package/vendor/framey/dist/chunk-3FYD4YEK.js +72 -0
  338. package/vendor/framey/dist/chunk-3GXQPCJC.js +682 -0
  339. package/vendor/framey/dist/chunk-3LM6YPBR.js +179 -0
  340. package/vendor/framey/dist/chunk-442JNXRM.js +20 -0
  341. package/vendor/framey/dist/chunk-4BNN5FGX.js +182 -0
  342. package/vendor/framey/dist/chunk-4P7NX5BM.js +11532 -0
  343. package/vendor/framey/dist/chunk-4UMPIPCQ.js +88 -0
  344. package/vendor/framey/dist/chunk-4YYJOFKS.js +28 -0
  345. package/vendor/framey/dist/chunk-54HJ63Q2.js +29 -0
  346. package/vendor/framey/dist/chunk-5ETJX6WM.js +89 -0
  347. package/vendor/framey/dist/chunk-5SG54JRS.js +68 -0
  348. package/vendor/framey/dist/chunk-634HSJ3J.js +58 -0
  349. package/vendor/framey/dist/chunk-66LREXGS.js +48 -0
  350. package/vendor/framey/dist/chunk-6BEFEWFB.js +25 -0
  351. package/vendor/framey/dist/chunk-6BNTGNGD.js +286 -0
  352. package/vendor/framey/dist/chunk-6DDPOHMK.js +140 -0
  353. package/vendor/framey/dist/chunk-6GV5XSOR.js +214 -0
  354. package/vendor/framey/dist/chunk-6JR2XUEE.js +127 -0
  355. package/vendor/framey/dist/chunk-73QVATIM.js +362 -0
  356. package/vendor/framey/dist/chunk-7FMUTGOH.js +279 -0
  357. package/vendor/framey/dist/chunk-7JQFJ6JJ.js +291 -0
  358. package/vendor/framey/dist/chunk-AHPGAESX.js +113 -0
  359. package/vendor/framey/dist/chunk-AHX34EFP.js +15 -0
  360. package/vendor/framey/dist/chunk-AJ5CSAEZ.js +487 -0
  361. package/vendor/framey/dist/chunk-B7RJV74O.js +5047 -0
  362. package/vendor/framey/dist/chunk-BL4U6U52.js +254 -0
  363. package/vendor/framey/dist/chunk-BSQ7XANM.js +210 -0
  364. package/vendor/framey/dist/chunk-BZ56MTDX.js +6 -0
  365. package/vendor/framey/dist/chunk-C5BO7PMT.js +282 -0
  366. package/vendor/framey/dist/chunk-CFUCHO4T.js +358 -0
  367. package/vendor/framey/dist/chunk-CZGHFATT.js +31 -0
  368. package/vendor/framey/dist/chunk-DLA44CMS.js +5649 -0
  369. package/vendor/framey/dist/chunk-DPVXBVLL.js +31292 -0
  370. package/vendor/framey/dist/chunk-DQBY7FRR.js +397 -0
  371. package/vendor/framey/dist/chunk-EAMLBAHA.js +154 -0
  372. package/vendor/framey/dist/chunk-EOVYQ3IG.js +143 -0
  373. package/vendor/framey/dist/chunk-EVMY7IPL.js +612 -0
  374. package/vendor/framey/dist/chunk-FG4BBFZI.js +122 -0
  375. package/vendor/framey/dist/chunk-FI4I7CME.js +56 -0
  376. package/vendor/framey/dist/chunk-FLREUEHW.js +2081 -0
  377. package/vendor/framey/dist/chunk-FUFP7A7S.js +1126 -0
  378. package/vendor/framey/dist/chunk-FV3PIKGH.js +56 -0
  379. package/vendor/framey/dist/chunk-FXMKHHPO.js +123 -0
  380. package/vendor/framey/dist/chunk-GGZAM5VH.js +1187 -0
  381. package/vendor/framey/dist/chunk-GKZEVJIB.js +39 -0
  382. package/vendor/framey/dist/chunk-GMECXFAN.js +57 -0
  383. package/vendor/framey/dist/chunk-GNEFDLFB.js +621 -0
  384. package/vendor/framey/dist/chunk-GPMLSOEG.js +19274 -0
  385. package/vendor/framey/dist/chunk-GPYVT5EE.js +59 -0
  386. package/vendor/framey/dist/chunk-H6IEMZEV.js +40 -0
  387. package/vendor/framey/dist/chunk-HEFQCIXR.js +170 -0
  388. package/vendor/framey/dist/chunk-HFQ4CWHA.js +118 -0
  389. package/vendor/framey/dist/chunk-HPDTCOKE.js +304 -0
  390. package/vendor/framey/dist/chunk-HTUHQKDB.js +548 -0
  391. package/vendor/framey/dist/chunk-HU2SPFNG.js +103 -0
  392. package/vendor/framey/dist/chunk-HVW7ABXD.js +19 -0
  393. package/vendor/framey/dist/chunk-IG7NDKXO.js +26 -0
  394. package/vendor/framey/dist/chunk-II3J3WXK.js +246 -0
  395. package/vendor/framey/dist/chunk-IR35BCLK.js +13 -0
  396. package/vendor/framey/dist/chunk-ISN5GRYI.js +20 -0
  397. package/vendor/framey/dist/chunk-IUONB55J.js +669 -0
  398. package/vendor/framey/dist/chunk-IVSUQR2B.js +161 -0
  399. package/vendor/framey/dist/chunk-IXU6PQSW.js +259 -0
  400. package/vendor/framey/dist/chunk-IZCW2NKT.js +29 -0
  401. package/vendor/framey/dist/chunk-JGXJU5PF.js +68 -0
  402. package/vendor/framey/dist/chunk-JHOCK3DG.js +27 -0
  403. package/vendor/framey/dist/chunk-JVBRJMOP.js +121 -0
  404. package/vendor/framey/dist/chunk-K4MJX7SR.js +17 -0
  405. package/vendor/framey/dist/chunk-K4WKGXRC.js +18 -0
  406. package/vendor/framey/dist/chunk-KGPLIH7B.js +127 -0
  407. package/vendor/framey/dist/chunk-KLIKCX6Q.js +63 -0
  408. package/vendor/framey/dist/chunk-KXTKKBOC.js +61 -0
  409. package/vendor/framey/dist/chunk-KZI44OPA.js +185 -0
  410. package/vendor/framey/dist/chunk-LEKZNRKI.js +45 -0
  411. package/vendor/framey/dist/chunk-LFGJWOVA.js +61 -0
  412. package/vendor/framey/dist/chunk-LLMSX6V6.js +17 -0
  413. package/vendor/framey/dist/chunk-LTGTN2TH.js +195 -0
  414. package/vendor/framey/dist/chunk-M2WBOQ2Q.js +54 -0
  415. package/vendor/framey/dist/chunk-MI5FTLYK.js +399 -0
  416. package/vendor/framey/dist/chunk-MLQP2QUF.js +1809 -0
  417. package/vendor/framey/dist/chunk-MMQ52NIZ.js +956 -0
  418. package/vendor/framey/dist/chunk-ND46XKK3.js +742 -0
  419. package/vendor/framey/dist/chunk-NYEXNSHM.js +504 -0
  420. package/vendor/framey/dist/chunk-O4YRB27L.js +57 -0
  421. package/vendor/framey/dist/chunk-O7BGSQ5F.js +92 -0
  422. package/vendor/framey/dist/chunk-OFQWTKPW.js +117 -0
  423. package/vendor/framey/dist/chunk-P5ZBLXJ6.js +91 -0
  424. package/vendor/framey/dist/chunk-P6LJ4Y32.js +4662 -0
  425. package/vendor/framey/dist/chunk-PKZ7RK5N.js +281 -0
  426. package/vendor/framey/dist/chunk-PURHAXFL.js +15 -0
  427. package/vendor/framey/dist/chunk-Q5X2B5WT.js +29 -0
  428. package/vendor/framey/dist/chunk-QAMKOG67.js +248 -0
  429. package/vendor/framey/dist/chunk-R6YBK4XX.js +514 -0
  430. package/vendor/framey/dist/chunk-RGLQURIX.js +2997 -0
  431. package/vendor/framey/dist/chunk-RNV3DM4S.js +3573 -0
  432. package/vendor/framey/dist/chunk-ROEW726S.js +4638 -0
  433. package/vendor/framey/dist/chunk-RQVDTPGD.js +6 -0
  434. package/vendor/framey/dist/chunk-RVZHGOGR.js +26 -0
  435. package/vendor/framey/dist/chunk-RXATE6FZ.js +385 -0
  436. package/vendor/framey/dist/chunk-S3S4TGEH.js +424 -0
  437. package/vendor/framey/dist/chunk-SDYDNHEE.js +11202 -0
  438. package/vendor/framey/dist/chunk-SSWBU67I.js +173 -0
  439. package/vendor/framey/dist/chunk-ST35C4K6.js +28 -0
  440. package/vendor/framey/dist/chunk-SZNTYTIV.js +990 -0
  441. package/vendor/framey/dist/chunk-T2EUWCJE.js +29 -0
  442. package/vendor/framey/dist/chunk-T6AGUTZJ.js +444 -0
  443. package/vendor/framey/dist/chunk-THJALHFJ.js +11131 -0
  444. package/vendor/framey/dist/chunk-TIQB63MX.js +18128 -0
  445. package/vendor/framey/dist/chunk-U242RTCT.js +134 -0
  446. package/vendor/framey/dist/chunk-UJZREAV6.js +3901 -0
  447. package/vendor/framey/dist/chunk-UMD3V7CU.js +264 -0
  448. package/vendor/framey/dist/chunk-UOFAE5RF.js +42 -0
  449. package/vendor/framey/dist/chunk-UTEIUGAZ.js +29 -0
  450. package/vendor/framey/dist/chunk-VAS6HQX3.js +138 -0
  451. package/vendor/framey/dist/chunk-VC76R6W2.js +27 -0
  452. package/vendor/framey/dist/chunk-VFZ7W5W7.js +226 -0
  453. package/vendor/framey/dist/chunk-VHNLZAE2.js +348 -0
  454. package/vendor/framey/dist/chunk-VMC4WSH5.js +278 -0
  455. package/vendor/framey/dist/chunk-VORQIH64.js +108 -0
  456. package/vendor/framey/dist/chunk-VTXFRIHO.js +186 -0
  457. package/vendor/framey/dist/chunk-W2LGJSEN.js +182 -0
  458. package/vendor/framey/dist/chunk-WKBM7NDG.js +32 -0
  459. package/vendor/framey/dist/chunk-WMQNIQDJ.js +2057 -0
  460. package/vendor/framey/dist/chunk-WN4XZC5F.js +504 -0
  461. package/vendor/framey/dist/chunk-WQ6ZXHFQ.js +133 -0
  462. package/vendor/framey/dist/chunk-X7HBSTCZ.js +53 -0
  463. package/vendor/framey/dist/chunk-X7MTZ4T2.js +6 -0
  464. package/vendor/framey/dist/chunk-XPTOJZJF.js +308 -0
  465. package/vendor/framey/dist/chunk-XT6MXC7A.js +6 -0
  466. package/vendor/framey/dist/chunk-XT7X6QCP.js +6 -0
  467. package/vendor/framey/dist/chunk-XTMDWNEC.js +2820 -0
  468. package/vendor/framey/dist/chunk-XUHOIDKG.js +6 -0
  469. package/vendor/framey/dist/chunk-XX7LTW5Y.js +138 -0
  470. package/vendor/framey/dist/chunk-Y3YGTZEG.js +382 -0
  471. package/vendor/framey/dist/chunk-Y5SBSGN7.js +346 -0
  472. package/vendor/framey/dist/chunk-YCMVI4MZ.js +625 -0
  473. package/vendor/framey/dist/chunk-YOR4CTCE.js +261 -0
  474. package/vendor/framey/dist/chunk-YPRBGITP.js +2748 -0
  475. package/vendor/framey/dist/chunk-ZKDMAOFU.js +32 -0
  476. package/vendor/framey/dist/chunk-ZW6DURPF.js +1318 -0
  477. package/vendor/framey/dist/clean-ZJOGDKDM.js +336 -0
  478. package/vendor/framey/dist/cli.js +439 -0
  479. package/vendor/framey/dist/cloudrun-HGJ3B6ZV.js +767 -0
  480. package/vendor/framey/dist/commands/contrast-audit.browser.js +643 -0
  481. package/vendor/framey/dist/commands/layout-audit.browser.js +2914 -0
  482. package/vendor/framey/dist/commands/motion-sample.browser.js +74 -0
  483. package/vendor/framey/dist/commands/motion-signature.browser.js +475 -0
  484. package/vendor/framey/dist/compare-W7UY3BAZ.js +463 -0
  485. package/vendor/framey/dist/compiler-TM3W6GYF.js +136 -0
  486. package/vendor/framey/dist/component-QF5VGYMU.js +176 -0
  487. package/vendor/framey/dist/compositions-XT3PMNDF.js +238 -0
  488. package/vendor/framey/dist/contactSheet-7W6GYHBQ.js +24 -0
  489. package/vendor/framey/dist/deploy-6FJPWKF2.js +299 -0
  490. package/vendor/framey/dist/destroy-HE2RIPKZ.js +57 -0
  491. package/vendor/framey/dist/deterministicFonts-RADD3BSX.js +50 -0
  492. package/vendor/framey/dist/dist-4S2FGGVY.js +422 -0
  493. package/vendor/framey/dist/dist-BE4B2EZE.js +32 -0
  494. package/vendor/framey/dist/dist-EWXJGN63.js +129 -0
  495. package/vendor/framey/dist/docs-VKIRFEEX.js +131 -0
  496. package/vendor/framey/dist/doctor-2UNJ2G7U.js +74 -0
  497. package/vendor/framey/dist/dom-37K6YOH4.js +14 -0
  498. package/vendor/framey/dist/dotEnv-7PZQTVIM.js +54 -0
  499. package/vendor/framey/dist/events-ACY3P2PA.js +76 -0
  500. package/vendor/framey/dist/events-IHB3B2MK.js +69 -0
  501. package/vendor/framey/dist/ffmpeg-DR5LGGSK.js +63 -0
  502. package/vendor/framey/dist/figma-BODVUPHB.js +63 -0
  503. package/vendor/framey/dist/fontData.generated-NXAOI4GH.js +13 -0
  504. package/vendor/framey/dist/fontLocalizeCli.js +142 -0
  505. package/vendor/framey/dist/gpuPolicy-XLEXORZY.js +49 -0
  506. package/vendor/framey/dist/grade-compare-GAXFQ74C.js +661 -0
  507. package/vendor/framey/dist/gsapParser-IEUSLYDJ.js +2885 -0
  508. package/vendor/framey/dist/gsapParserAcorn-LZJKCFQI.js +30 -0
  509. package/vendor/framey/dist/help-VCB5X2HS.js +184 -0
  510. package/vendor/framey/dist/history-ENGZEVFT.js +471 -0
  511. package/vendor/framey/dist/hyperframe.manifest.json +22 -0
  512. package/vendor/framey/dist/hyperframe.runtime.iife.js +1132 -0
  513. package/vendor/framey/dist/hyperframes-player.global.js +478 -0
  514. package/vendor/framey/dist/hyperframes-slideshow.global.js +148 -0
  515. package/vendor/framey/dist/info-WPCJHBMU.js +182 -0
  516. package/vendor/framey/dist/init-G4WGLYGD.js +1176 -0
  517. package/vendor/framey/dist/inspect-5IQ6CNEQ.js +106 -0
  518. package/vendor/framey/dist/installer-ML4HWUV7.js +40 -0
  519. package/vendor/framey/dist/keyframes-Q6XJO7VW.js +2755 -0
  520. package/vendor/framey/dist/lambda-A7JC74JF.js +468 -0
  521. package/vendor/framey/dist/layout-YET6XNXA.js +95 -0
  522. package/vendor/framey/dist/lint-I7FZN2VJ.js +162 -0
  523. package/vendor/framey/dist/lintProject-PDB3UN72.js +30 -0
  524. package/vendor/framey/dist/manager-CD6LJ7ZN.js +45 -0
  525. package/vendor/framey/dist/manager-WA4F2GST.js +67 -0
  526. package/vendor/framey/dist/media-treatment-BXYS4WVA.js +1030 -0
  527. package/vendor/framey/dist/media-use-LWH3MANK.js +113 -0
  528. package/vendor/framey/dist/models-K363FYM4.js +195 -0
  529. package/vendor/framey/dist/motionShot-GPAVWXLH.js +640 -0
  530. package/vendor/framey/dist/normalize-FASIPBUM.js +24 -0
  531. package/vendor/framey/dist/normalize-audio-VDWYRHN6.js +268 -0
  532. package/vendor/framey/dist/open-E3TB6P6J.js +128 -0
  533. package/vendor/framey/dist/parakeetRunner-UP34UOI2.js +58 -0
  534. package/vendor/framey/dist/pipeline-VXIUYEBU.js +64 -0
  535. package/vendor/framey/dist/play-BUTDQ4DV.js +353 -0
  536. package/vendor/framey/dist/policies-OLDYGFK5.js +309 -0
  537. package/vendor/framey/dist/preflight-2KZ2GWAZ.js +55 -0
  538. package/vendor/framey/dist/present-GXYSM7NX.js +353 -0
  539. package/vendor/framey/dist/preview-EKZ33JOJ.js +1910 -0
  540. package/vendor/framey/dist/producer-SKU5EV3J.js +13 -0
  541. package/vendor/framey/dist/progress-ZWB4Z4ET.js +76 -0
  542. package/vendor/framey/dist/projectConfig-3MZAYVTS.js +60 -0
  543. package/vendor/framey/dist/publication-DTKWNF74.js +33 -0
  544. package/vendor/framey/dist/remove-background-OY5L7XN2.js +265 -0
  545. package/vendor/framey/dist/render-CDV4GDFX.js +187 -0
  546. package/vendor/framey/dist/render-YE5YAMOD.js +2620 -0
  547. package/vendor/framey/dist/render-batch-ZAMFPCLL.js +274 -0
  548. package/vendor/framey/dist/renderSetupWorker.js +120 -0
  549. package/vendor/framey/dist/resolver-D5BIPSEW.js +42 -0
  550. package/vendor/framey/dist/runtimeVersion.js +18 -0
  551. package/vendor/framey/dist/sam-WFZXI4F7.js +23 -0
  552. package/vendor/framey/dist/shaderTransitionWorker.js +44 -0
  553. package/vendor/framey/dist/sherpa-RQWLV7I3.js +79 -0
  554. package/vendor/framey/dist/sherpaWorker.js +84 -0
  555. package/vendor/framey/dist/sites-AMOVABTK.js +54 -0
  556. package/vendor/framey/dist/skill-ZHVLH7KX.js +15 -0
  557. package/vendor/framey/dist/slideshow-SJGK4RQS.js +24 -0
  558. package/vendor/framey/dist/snapshot-TUXL6LBQ.js +1515 -0
  559. package/vendor/framey/dist/src-JHQGB2S6.js +215 -0
  560. package/vendor/framey/dist/src-Z5PGEMXB.js +532 -0
  561. package/vendor/framey/dist/state-B6H3WHCF.js +28 -0
  562. package/vendor/framey/dist/staticProjectServer-DFVZOUGI.js +63 -0
  563. package/vendor/framey/dist/studio/assets/hyperframes-player-DLaKjw0L.js +478 -0
  564. package/vendor/framey/dist/studio/assets/index-BX3KHhGX.js +71 -0
  565. package/vendor/framey/dist/studio/assets/index-CYbvOVp-.css +1 -0
  566. package/vendor/framey/dist/studio/assets/index-Dp3QEUGL.js +402 -0
  567. package/vendor/framey/dist/studio/assets/index-qrTAXbqc.js +531 -0
  568. package/vendor/framey/dist/studio/favicon.svg +14 -0
  569. package/vendor/framey/dist/studio/icons/timeline/audio.svg +7 -0
  570. package/vendor/framey/dist/studio/icons/timeline/captions.svg +5 -0
  571. package/vendor/framey/dist/studio/icons/timeline/composition.svg +12 -0
  572. package/vendor/framey/dist/studio/icons/timeline/image.svg +18 -0
  573. package/vendor/framey/dist/studio/icons/timeline/music.svg +10 -0
  574. package/vendor/framey/dist/studio/icons/timeline/text.svg +3 -0
  575. package/vendor/framey/dist/studio/index.html +23 -0
  576. package/vendor/framey/dist/studio-api-2NECGRMB.js +179 -0
  577. package/vendor/framey/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
  578. package/vendor/framey/dist/studioServer-N2OPUMOQ.js +1569 -0
  579. package/vendor/framey/dist/synthesize-PKTB5ATG.js +183 -0
  580. package/vendor/framey/dist/system-7F3UEHQT.js +27 -0
  581. package/vendor/framey/dist/telemetry-DQGPEKM6.js +145 -0
  582. package/vendor/framey/dist/telemetry-UN55N6U6.js +77 -0
  583. package/vendor/framey/dist/timeline-LHUUMK63.js +1295 -0
  584. package/vendor/framey/dist/tokens-OLECWDFK.js +92 -0
  585. package/vendor/framey/dist/transcribe-O7HQKMIV.js +331 -0
  586. package/vendor/framey/dist/transcribe-UJESPBT5.js +76 -0
  587. package/vendor/framey/dist/tts-YCCQHZD4.js +234 -0
  588. package/vendor/framey/dist/urlDownloader-H2LXLG4U.js +48 -0
  589. package/vendor/framey/dist/usage-HG4WMM7A.js +2167 -0
  590. package/vendor/framey/dist/validate-F2XMN6EV.js +87 -0
  591. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/GSAP-LICENSE.txt +8 -0
  592. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/CustomEase.min.js +11 -0
  593. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/MotionPathPlugin.min.js +11 -0
  594. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/gsap.min.js +11 -0
  595. package/vendor/framey/dist/warmCheck.js +220 -0
  596. package/vendor/framey/dist/warmCheckClient.js +139 -0
  597. package/vendor/framey/dist/workspaceBuildCheck-XYD2YTFW.js +133 -0
  598. package/vendor/framey-player/LICENSE +190 -0
  599. package/vendor/framey-player/NOTICE +16 -0
  600. package/vendor/framey-player/SOURCE.json +6 -0
  601. package/vendor/framey-player/hyperframes-player.global.js +478 -0
  602. package/vendor/framey.pin +1 -0
  603. package/bin/index.js +0 -3
@@ -0,0 +1,1569 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ renderJobObservabilityTelemetryPayload,
9
+ renderObservabilityTelemetryPayload,
10
+ startRenderCpuSampler
11
+ } from "./chunk-SSWBU67I.js";
12
+ import {
13
+ HANDOFF_READY,
14
+ desktopDownloadUrl,
15
+ desktopInstalled,
16
+ openInDesktop
17
+ } from "./chunk-VTXFRIHO.js";
18
+ import {
19
+ resolveRenderBrowser
20
+ } from "./chunk-2K7Z2HVP.js";
21
+ import "./chunk-VFZ7W5W7.js";
22
+ import {
23
+ loadSharpInBackground
24
+ } from "./chunk-VMC4WSH5.js";
25
+ import "./chunk-6BEFEWFB.js";
26
+ import "./chunk-UMD3V7CU.js";
27
+ import {
28
+ PREVIEW_BUNDLE_OPTIONS,
29
+ affectsPreview,
30
+ clearElementScreenshotIsolation,
31
+ compositionsAffectedBy,
32
+ createBackgroundRemovalJob,
33
+ createPreviewDocumentStore,
34
+ createStudioApi,
35
+ getElementScreenshotClip,
36
+ getMimeType,
37
+ stampProjectHfIds,
38
+ thumbnailDeviceScaleFactor
39
+ } from "./chunk-THJALHFJ.js";
40
+ import "./chunk-IUONB55J.js";
41
+ import "./chunk-6JR2XUEE.js";
42
+ import "./chunk-MI5FTLYK.js";
43
+ import {
44
+ DEFAULT_HISTORY_ROOT,
45
+ DELETED_VERSION,
46
+ HistoryBusyError,
47
+ HistoryClosedError,
48
+ STUDIO_SIGNATURE_MANIFEST_PATHS,
49
+ affectsProjectSignature,
50
+ createProjectSignature,
51
+ fileContentVersion,
52
+ historyCache,
53
+ identifyFileWrite,
54
+ openProjectHistory
55
+ } from "./chunk-YPRBGITP.js";
56
+ import "./chunk-7JQFJ6JJ.js";
57
+ import {
58
+ seekCompositionTimeline
59
+ } from "./chunk-SZNTYTIV.js";
60
+ import "./chunk-YOR4CTCE.js";
61
+ import "./chunk-KXTKKBOC.js";
62
+ import "./chunk-P5ZBLXJ6.js";
63
+ import "./chunk-LEKZNRKI.js";
64
+ import "./chunk-442JNXRM.js";
65
+ import {
66
+ resolveAutoProxy
67
+ } from "./chunk-4BNN5FGX.js";
68
+ import "./chunk-XT7X6QCP.js";
69
+ import "./chunk-4YYJOFKS.js";
70
+ import "./chunk-HVW7ABXD.js";
71
+ import {
72
+ resolveCaptureBrowserGpuMode,
73
+ resolveLocalBrowserGpuMode,
74
+ resolveLocalWebGpu
75
+ } from "./chunk-WKBM7NDG.js";
76
+ import "./chunk-XX7LTW5Y.js";
77
+ import "./chunk-JHOCK3DG.js";
78
+ import "./chunk-XPTOJZJF.js";
79
+ import "./chunk-RGLQURIX.js";
80
+ import "./chunk-P6LJ4Y32.js";
81
+ import "./chunk-GMECXFAN.js";
82
+ import "./chunk-FLREUEHW.js";
83
+ import {
84
+ isAtomicTempPath,
85
+ replaceFileAtomically
86
+ } from "./chunk-EOVYQ3IG.js";
87
+ import {
88
+ trackRenderComplete,
89
+ trackRenderError
90
+ } from "./chunk-GNEFDLFB.js";
91
+ import {
92
+ canaryDecisionsForStudio,
93
+ resetTelemetryPostureCache,
94
+ shouldTrack
95
+ } from "./chunk-2UZQHDM7.js";
96
+ import {
97
+ readConfig,
98
+ readConfigFresh
99
+ } from "./chunk-NYEXNSHM.js";
100
+ import "./chunk-54HJ63Q2.js";
101
+ import {
102
+ isDevMode
103
+ } from "./chunk-ISN5GRYI.js";
104
+ import "./chunk-VORQIH64.js";
105
+ import "./chunk-JVBRJMOP.js";
106
+ import "./chunk-KLIKCX6Q.js";
107
+ import {
108
+ createStudioManualEditsRenderBodyScript,
109
+ isProjectIgnoredDir
110
+ } from "./chunk-EVMY7IPL.js";
111
+ import "./chunk-7FMUTGOH.js";
112
+ import {
113
+ assertWebGpuAdapterAvailable,
114
+ compositionRequiresWebGpu
115
+ } from "./chunk-TIQB63MX.js";
116
+ import "./chunk-IZCW2NKT.js";
117
+ import "./chunk-RNV3DM4S.js";
118
+ import {
119
+ GSAP_CDN_VERSION,
120
+ fpsToNumber
121
+ } from "./chunk-DLA44CMS.js";
122
+ import "./chunk-UJZREAV6.js";
123
+ import "./chunk-VC76R6W2.js";
124
+ import "./chunk-X7HBSTCZ.js";
125
+ import "./chunk-B7RJV74O.js";
126
+ import "./chunk-DPVXBVLL.js";
127
+ import {
128
+ realpath
129
+ } from "./chunk-OFQWTKPW.js";
130
+ import "./chunk-634HSJ3J.js";
131
+ import "./chunk-FXMKHHPO.js";
132
+ import "./chunk-RQVDTPGD.js";
133
+ import {
134
+ VERSION
135
+ } from "./chunk-AHX34EFP.js";
136
+ import "./chunk-ND46XKK3.js";
137
+ import {
138
+ runRenderSetupWorker
139
+ } from "./chunk-BL4U6U52.js";
140
+ import "./chunk-T2EUWCJE.js";
141
+ import {
142
+ bytesToMb,
143
+ detectAgentRuntime
144
+ } from "./chunk-T6AGUTZJ.js";
145
+ import "./chunk-XT6MXC7A.js";
146
+ import "./chunk-K4MJX7SR.js";
147
+ import "./chunk-4UMPIPCQ.js";
148
+ import "./chunk-4P7NX5BM.js";
149
+ import "./chunk-VAS6HQX3.js";
150
+ import {
151
+ isWithinProjectRoot
152
+ } from "./chunk-6BNTGNGD.js";
153
+ import "./chunk-CZGHFATT.js";
154
+ import "./chunk-PKZ7RK5N.js";
155
+ import "./chunk-W2LGJSEN.js";
156
+ import "./chunk-MMQ52NIZ.js";
157
+ import "./chunk-BSQ7XANM.js";
158
+ import "./chunk-SDYDNHEE.js";
159
+ import "./chunk-RXATE6FZ.js";
160
+ import "./chunk-3422KMTD.js";
161
+ import "./chunk-KGPLIH7B.js";
162
+ import "./chunk-3GXQPCJC.js";
163
+ import "./chunk-M2WBOQ2Q.js";
164
+
165
+ // src/server/studioServer.ts
166
+ import { Hono } from "hono";
167
+ import { streamSSE } from "hono/streaming";
168
+ import { existsSync as existsSync2, readFileSync as readFileSync2, statSync as statSync2, writeFileSync, unlinkSync } from "fs";
169
+ import { createHash as createHash2 } from "crypto";
170
+ import { fileURLToPath } from "url";
171
+ import { resolve as resolve2, join as join2, basename as basename2, dirname as dirname3, relative as relative2, sep as sep2 } from "path";
172
+ import { createRequire } from "module";
173
+
174
+ // src/server/readBundleFile.ts
175
+ import { openSync, fstatSync, closeSync, statSync, readFileSync, constants } from "fs";
176
+ function readBundleFile(filePath) {
177
+ let fd;
178
+ try {
179
+ fd = openSync(filePath, constants.O_RDONLY | constants.O_NONBLOCK);
180
+ } catch (error) {
181
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
182
+ return null;
183
+ if (!statSync(filePath, { throwIfNoEntry: false })?.isFile()) return null;
184
+ throw error;
185
+ }
186
+ try {
187
+ if (!fstatSync(fd).isFile()) return null;
188
+ return readFileSync(fd);
189
+ } finally {
190
+ closeSync(fd);
191
+ }
192
+ }
193
+
194
+ // src/server/fileWatcher.ts
195
+ import { lstatSync, readdirSync, watch } from "fs";
196
+ import { basename, dirname, join, relative, sep } from "path";
197
+ var QUIET_MS = 30;
198
+ var BURST_MS = 300;
199
+ function shouldWatchProjectFile(filename) {
200
+ if (!filename || isAtomicTempPath(filename)) return false;
201
+ const parts = filename.split(/[\\/]+/);
202
+ return !parts.some(isProjectIgnoredDir);
203
+ }
204
+ function isDirectory(path) {
205
+ try {
206
+ return lstatSync(path).isDirectory();
207
+ } catch {
208
+ return false;
209
+ }
210
+ }
211
+ function watchProjectTree(projectDir, onChange) {
212
+ if (process.platform !== "linux") {
213
+ const tree = watch(projectDir, { recursive: true }, (_event, filename) => {
214
+ if (filename) onChange(filename.toString());
215
+ });
216
+ tree.on("error", () => tree.close());
217
+ return () => tree.close();
218
+ }
219
+ const directories = /* @__PURE__ */ new Map();
220
+ const unwatch = (dir) => {
221
+ for (const [watched, watcher] of directories) {
222
+ if (watched === dir || watched.startsWith(dir + sep)) {
223
+ watcher.close();
224
+ directories.delete(watched);
225
+ }
226
+ }
227
+ };
228
+ const watchDirectory = (dir, movedIn = false) => {
229
+ if (directories.has(dir)) unwatch(dir);
230
+ let watcher;
231
+ try {
232
+ watcher = watch(dir, { persistent: true }, (event, name) => {
233
+ if (!name) return;
234
+ const path = join(dir, name.toString());
235
+ onChange(relative(projectDir, path));
236
+ if (event !== "rename") return;
237
+ if (isDirectory(path)) descend(path, true);
238
+ else unwatch(path);
239
+ });
240
+ } catch {
241
+ return;
242
+ }
243
+ watcher.on("error", () => unwatch(dir));
244
+ directories.set(dir, watcher);
245
+ walkChildren(dir, movedIn);
246
+ };
247
+ const walkChildren = (dir, movedIn) => {
248
+ let entries = [];
249
+ try {
250
+ entries = readdirSync(dir, { withFileTypes: true });
251
+ } catch {
252
+ }
253
+ for (const entry of entries) {
254
+ const child = join(dir, entry.name);
255
+ if (entry.isDirectory()) descend(child, movedIn);
256
+ else if (movedIn) onChange(relative(projectDir, child));
257
+ }
258
+ if (movedIn && relative(projectDir, dir) === ".hyperframes") {
259
+ for (const manifest of STUDIO_SIGNATURE_MANIFEST_PATHS) onChange(manifest);
260
+ }
261
+ };
262
+ const descend = (dir, movedIn = false) => {
263
+ const rel = relative(projectDir, dir);
264
+ if (shouldWatchProjectFile(rel) || rel === ".hyperframes") watchDirectory(dir, movedIn);
265
+ };
266
+ let parent = null;
267
+ try {
268
+ parent = watch(dirname(projectDir), { persistent: true }, (event, name) => {
269
+ if (event !== "rename" || name?.toString() !== basename(projectDir)) return;
270
+ watchDirectory(projectDir);
271
+ onChange(".");
272
+ });
273
+ parent.on("error", () => parent?.close());
274
+ } catch {
275
+ }
276
+ watchDirectory(projectDir);
277
+ return () => {
278
+ parent?.close();
279
+ for (const watcher of directories.values()) watcher.close();
280
+ directories.clear();
281
+ };
282
+ }
283
+ function createProjectWatcher(projectDir) {
284
+ const listeners = /* @__PURE__ */ new Set();
285
+ const pendingPaths = /* @__PURE__ */ new Set();
286
+ let debounceTimer = null;
287
+ let lastFlushAt = Number.NEGATIVE_INFINITY;
288
+ let closeTree = null;
289
+ try {
290
+ closeTree = watchProjectTree(projectDir, (relativePath) => {
291
+ if (!shouldWatchProjectFile(relativePath) && !affectsProjectSignature(projectDir, join(projectDir, relativePath))) {
292
+ return;
293
+ }
294
+ pendingPaths.add(relativePath);
295
+ if (debounceTimer) clearTimeout(debounceTimer);
296
+ const delay = Math.max(QUIET_MS, lastFlushAt + BURST_MS - Date.now());
297
+ debounceTimer = setTimeout(() => {
298
+ const changedPaths = [...pendingPaths];
299
+ pendingPaths.clear();
300
+ debounceTimer = null;
301
+ lastFlushAt = Date.now();
302
+ for (const changedPath of changedPaths) {
303
+ for (const fn of listeners) {
304
+ fn(changedPath);
305
+ }
306
+ }
307
+ }, delay);
308
+ });
309
+ } catch {
310
+ }
311
+ return {
312
+ addListener(fn) {
313
+ listeners.add(fn);
314
+ },
315
+ removeListener(fn) {
316
+ listeners.delete(fn);
317
+ },
318
+ close() {
319
+ if (debounceTimer) clearTimeout(debounceTimer);
320
+ pendingPaths.clear();
321
+ closeTree?.();
322
+ listeners.clear();
323
+ }
324
+ };
325
+ }
326
+
327
+ // src/server/runtimeSource.ts
328
+ import { createHash } from "crypto";
329
+ import { existsSync } from "fs";
330
+ import { resolve, dirname as dirname2 } from "path";
331
+ var ARTIFACT_NAMES = ["hyperframe-runtime.js", "hyperframe.runtime.iife.js"];
332
+ async function loadRuntimeSource() {
333
+ return await buildFromSource() ?? await getInlinedRuntime() ?? readPrebuiltArtifact();
334
+ }
335
+ async function loadRuntimeSourceSignature() {
336
+ const source = await loadRuntimeSource();
337
+ if (!source) return null;
338
+ return createHash("sha256").update(source).digest("hex");
339
+ }
340
+ function hashSignatureParts(parts) {
341
+ const hash = createHash("sha256");
342
+ for (const part of parts) {
343
+ hash.update(part ?? "");
344
+ hash.update("\n--hf-signature-part--\n");
345
+ }
346
+ return hash.digest("hex");
347
+ }
348
+ var ENTRY_TS = resolve(__dirname, "..", "..", "..", "core", "src", "runtime", "entry.ts");
349
+ async function buildFromSource() {
350
+ if (!existsSync(ENTRY_TS)) return null;
351
+ try {
352
+ const mod = await import("./dist-4S2FGGVY.js");
353
+ if (typeof mod.loadHyperframeRuntimeSource === "function") {
354
+ const source = mod.loadHyperframeRuntimeSource();
355
+ if (source) return source;
356
+ }
357
+ } catch {
358
+ }
359
+ return null;
360
+ }
361
+ async function getInlinedRuntime() {
362
+ try {
363
+ const mod = await import("./dist-4S2FGGVY.js");
364
+ if (typeof mod.getHyperframeRuntimeScript === "function") {
365
+ return mod.getHyperframeRuntimeScript() ?? null;
366
+ }
367
+ } catch {
368
+ }
369
+ return null;
370
+ }
371
+ function readPrebuiltArtifact() {
372
+ return readFromDir(__dirname) ?? readFromCoreDistDir() ?? readFromNodeModules();
373
+ }
374
+ function readFromDir(dir) {
375
+ for (const name of ARTIFACT_NAMES) {
376
+ const path = resolve(dir, name);
377
+ const content = readBundleFile(path);
378
+ if (content !== null) return content.toString("utf-8");
379
+ }
380
+ return null;
381
+ }
382
+ function readFromCoreDistDir() {
383
+ return readFromDir(resolve(__dirname, "..", "..", "..", "core", "dist"));
384
+ }
385
+ function readFromNodeModules() {
386
+ const subPaths = ["node_modules/hyperframes/dist", "node_modules/@framey/core/dist"];
387
+ let dir = __dirname;
388
+ for (; ; ) {
389
+ for (const sub of subPaths) {
390
+ const result = readFromDir(resolve(dir, sub));
391
+ if (result) return result;
392
+ }
393
+ const parent = dirname2(dir);
394
+ if (parent === dir) break;
395
+ dir = parent;
396
+ }
397
+ return null;
398
+ }
399
+
400
+ // src/server/telemetryIdentity.ts
401
+ import { hostname, networkInterfaces } from "os";
402
+ function resolveCliTelemetryDistinctId() {
403
+ try {
404
+ if (!shouldTrack()) return null;
405
+ const id = readConfig().anonymousId;
406
+ return typeof id === "string" && id.length > 0 ? id : null;
407
+ } catch {
408
+ return null;
409
+ }
410
+ }
411
+ function resolveCliBucketSeed() {
412
+ try {
413
+ if (!shouldTrack()) return null;
414
+ const seed = readConfig().bucketSeed;
415
+ return typeof seed === "string" && seed.length > 0 ? seed : null;
416
+ } catch {
417
+ return null;
418
+ }
419
+ }
420
+ function isLoopbackHost(host) {
421
+ if (!host) return false;
422
+ const bracketed = /^\[([^\]]+)\]/.exec(host);
423
+ const hostname2 = (bracketed ? bracketed[1] : host.split(":")[0])?.toLowerCase() ?? "";
424
+ if (hostname2 === "localhost" || hostname2 === "::1" || hostname2 === "0:0:0:0:0:0:0:1") return true;
425
+ return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname2);
426
+ }
427
+ function encodeInlineScriptValue(value) {
428
+ return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\//g, "\\/");
429
+ }
430
+ function encodeInlineScriptJson(value) {
431
+ return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\//g, "\\/");
432
+ }
433
+ function resolveCliCanaryDecisions() {
434
+ try {
435
+ const decisions = canaryDecisionsForStudio();
436
+ return Object.keys(decisions).length > 0 ? decisions : null;
437
+ } catch {
438
+ return null;
439
+ }
440
+ }
441
+ function buildCliIdentityScript(options = {}) {
442
+ const { includeIdentity = true } = options;
443
+ const parts = [];
444
+ parts.push(`window.__HF_CLI_TELEMETRY_DISABLED=${!shouldTrack()};`);
445
+ const cliId = includeIdentity ? resolveCliTelemetryDistinctId() : null;
446
+ if (cliId) {
447
+ parts.push(`window.__HF_CLI_DISTINCT_ID=${encodeInlineScriptValue(cliId)};`);
448
+ const seed = resolveCliBucketSeed();
449
+ if (seed) parts.push(`window.__HF_CLI_BUCKET_SEED=${encodeInlineScriptValue(seed)};`);
450
+ }
451
+ const decisions = resolveCliCanaryDecisions();
452
+ if (decisions !== null) {
453
+ parts.push(`window.__HF_CLI_CANARY_DECISIONS=${encodeInlineScriptJson(decisions)};`);
454
+ }
455
+ const agent = shouldTrack() ? detectAgentRuntime() : null;
456
+ if (agent) {
457
+ parts.push(`window.__HF_CLI_AGENT_RUNTIME=${encodeInlineScriptValue(agent)};`);
458
+ }
459
+ return parts.length === 0 ? "" : `<script>${parts.join("")}</script>`;
460
+ }
461
+ function buildStudioHeadScripts(envScript, options = {}) {
462
+ return `${buildCliIdentityScript(options)}${envScript}`;
463
+ }
464
+ function hostnameOf(host) {
465
+ if (!host) return "";
466
+ const bracketed = /^\[([^\]]+)\]/.exec(host);
467
+ return (bracketed ? bracketed[1] : host.split(":")[0])?.toLowerCase() ?? "";
468
+ }
469
+ function localNames() {
470
+ const names = /* @__PURE__ */ new Set();
471
+ try {
472
+ for (const entries of Object.values(networkInterfaces())) {
473
+ for (const entry of entries ?? []) names.add(entry.address.toLowerCase());
474
+ }
475
+ const self = hostname().toLowerCase();
476
+ if (self !== "") {
477
+ names.add(self);
478
+ names.add(`${self}.local`);
479
+ const short = self.split(".")[0];
480
+ if (short !== void 0 && short !== "") {
481
+ names.add(short);
482
+ names.add(`${short}.local`);
483
+ }
484
+ }
485
+ } catch {
486
+ }
487
+ return names;
488
+ }
489
+ function hostMatchesBind(host, bind) {
490
+ const requested = hostnameOf(host);
491
+ if (requested === "") return false;
492
+ const bound = bind.toLowerCase();
493
+ if (requested === bound) return true;
494
+ return bound === "0.0.0.0" || bound === "::" || bound === "*" ? localNames().has(requested) : false;
495
+ }
496
+ function identityAllowed(host) {
497
+ if (isLoopbackHost(host)) return true;
498
+ const bind = (process.env["HYPERFRAMES_PREVIEW_HOST"] ?? "").trim();
499
+ if (bind === "" || isLoopbackHost(bind)) return false;
500
+ return hostMatchesBind(host, bind);
501
+ }
502
+ function refreshTelemetryPosture() {
503
+ try {
504
+ readConfigFresh();
505
+ resetTelemetryPostureCache();
506
+ } catch {
507
+ }
508
+ }
509
+ function buildStudioHeadScriptsForHost(envScript, host) {
510
+ refreshTelemetryPosture();
511
+ return buildStudioHeadScripts(envScript, { includeIdentity: identityAllowed(host) });
512
+ }
513
+
514
+ // src/server/studioRenderTelemetry.ts
515
+ import { freemem } from "os";
516
+ function memSnapshot() {
517
+ return {
518
+ peakMemoryMb: bytesToMb(process.memoryUsage.rss()),
519
+ memoryFreeMb: bytesToMb(freemem())
520
+ };
521
+ }
522
+ function stagesPayload(stages) {
523
+ return {
524
+ stageCompileMs: stages.compileMs,
525
+ stageVideoExtractMs: stages.videoExtractMs,
526
+ stageAudioProcessMs: stages.audioProcessMs,
527
+ stageCaptureMs: stages.captureMs,
528
+ stageCaptureSetupMs: stages.captureSetupMs,
529
+ stageCaptureFrameMs: stages.captureFrameMs,
530
+ stageEncodeMs: stages.encodeMs,
531
+ stageAssembleMs: stages.assembleMs
532
+ };
533
+ }
534
+ function extractPayload(extract) {
535
+ if (!extract) return {};
536
+ return {
537
+ extractResolveMs: extract.resolveMs,
538
+ extractHdrProbeMs: extract.hdrProbeMs,
539
+ extractHdrPreflightMs: extract.hdrPreflightMs,
540
+ extractHdrPreflightCount: extract.hdrPreflightCount,
541
+ extractVfrProbeMs: extract.vfrProbeMs,
542
+ extractVfrPreflightMs: extract.vfrPreflightMs,
543
+ extractVfrPreflightCount: extract.vfrPreflightCount,
544
+ extractPhase3Ms: extract.extractMs,
545
+ extractCacheHits: extract.cacheHits,
546
+ extractCacheMisses: extract.cacheMisses
547
+ };
548
+ }
549
+ function perfPayload(perf, elapsedMs) {
550
+ if (!perf) return {};
551
+ const compositionDurationMs = Math.round(perf.compositionDurationSeconds * 1e3);
552
+ const speedRatio = compositionDurationMs > 0 && elapsedMs > 0 ? Math.round(compositionDurationMs / elapsedMs * 100) / 100 : void 0;
553
+ return {
554
+ workers: perf.workers,
555
+ compositionDurationMs,
556
+ compositionWidth: perf.resolution.width,
557
+ compositionHeight: perf.resolution.height,
558
+ totalFrames: perf.totalFrames,
559
+ speedRatio,
560
+ captureAvgMs: perf.captureAvgMs,
561
+ capturePeakMs: perf.capturePeakMs,
562
+ tmpPeakBytes: perf.tmpPeakBytes,
563
+ ...stagesPayload(perf.stages),
564
+ ...extractPayload(perf.videoExtractBreakdown),
565
+ ...renderObservabilityTelemetryPayload(perf.observability)
566
+ };
567
+ }
568
+ function emitStudioRenderError(opts, elapsedMs, failedStage, err, job, cpuUsage = {}) {
569
+ if (opts.telemetryOptOut === true) return;
570
+ trackRenderError({
571
+ fps: fpsToNumber(opts.fps),
572
+ quality: opts.quality,
573
+ docker: false,
574
+ gpu: opts.useGpu === true,
575
+ source: "studio",
576
+ failedStage,
577
+ errorMessage: err instanceof Error ? err.message : String(err),
578
+ elapsedMs,
579
+ outputFormat: opts.format,
580
+ outputResolutionPreset: opts.outputResolution,
581
+ distinctId: opts.distinctId,
582
+ ...renderJobObservabilityTelemetryPayload(job),
583
+ ...memSnapshot(),
584
+ ...cpuUsage
585
+ });
586
+ }
587
+ function emitStudioRenderComplete(opts, elapsedMs, perf, cpuUsage = {}) {
588
+ if (opts.telemetryOptOut === true) return;
589
+ trackRenderComplete({
590
+ durationMs: elapsedMs,
591
+ fps: fpsToNumber(opts.fps),
592
+ quality: opts.quality,
593
+ docker: false,
594
+ gpu: opts.useGpu === true,
595
+ source: "studio",
596
+ outputFormat: opts.format,
597
+ outputResolutionPreset: opts.outputResolution,
598
+ distinctId: opts.distinctId,
599
+ ...perfPayload(perf, elapsedMs),
600
+ ...memSnapshot(),
601
+ ...cpuUsage
602
+ });
603
+ }
604
+
605
+ // src/server/desktopRoutes.ts
606
+ var CTA_ID = /^[A-Za-z0-9-]{1,64}$/;
607
+ function sameOriginPost(headers) {
608
+ const { host, origin, fetchSite } = headers;
609
+ if (!host || !identityAllowed(host)) return false;
610
+ if (fetchSite && fetchSite !== "same-origin") return false;
611
+ return origin === void 0 || origin === `http://${host}`;
612
+ }
613
+ function mountDesktopRoutes(app, projectDir, {
614
+ ready = HANDOFF_READY,
615
+ open = (dir, cta) => openInDesktop(dir, { cta }),
616
+ platform = process.platform,
617
+ installed = () => desktopInstalled({ platform })
618
+ } = {}) {
619
+ const downloadUrl = desktopDownloadUrl(platform);
620
+ app.get("/api/open-in-desktop", (c) => {
621
+ const here = installed();
622
+ return c.json({
623
+ available: downloadUrl !== null || here,
624
+ handoff: ready && here,
625
+ downloadUrl,
626
+ os: platform,
627
+ installed: here
628
+ });
629
+ });
630
+ app.post("/api/open-in-desktop", async (c) => {
631
+ const allowed = sameOriginPost({
632
+ host: c.req.header("host"),
633
+ origin: c.req.header("origin"),
634
+ fetchSite: c.req.header("sec-fetch-site")
635
+ });
636
+ if (!allowed) return c.json({ error: "forbidden" }, 403);
637
+ if (!ready)
638
+ return c.json({
639
+ opened: false,
640
+ reason: "handoff-unavailable",
641
+ downloadUrl
642
+ });
643
+ const body = await c.req.json().catch(() => null);
644
+ const cta = body?.cta;
645
+ return c.json(open(projectDir, typeof cta === "string" && CTA_ID.test(cta) ? cta : void 0));
646
+ });
647
+ }
648
+
649
+ // src/server/thumbnailPages.ts
650
+ function createThumbnailPages(maxPages = 2, idleMs = 1e3) {
651
+ const pages = /* @__PURE__ */ new Map();
652
+ const drop = (url) => {
653
+ const entry = pages.get(url);
654
+ if (!entry) return;
655
+ pages.delete(url);
656
+ clearTimeout(entry.idleTimer);
657
+ void entry.queue.then(() => entry.page).then((page) => page.close()).catch(() => {
658
+ });
659
+ };
660
+ const entryFor = (browser, url, version, time, load) => {
661
+ const existing = pages.get(url);
662
+ if (existing && existing.browser === browser && existing.version === version && existing.shownUpTo <= time) {
663
+ existing.shownUpTo = time;
664
+ return existing;
665
+ }
666
+ drop(url);
667
+ const page = browser.newPage().then(async (created) => {
668
+ try {
669
+ await load(created);
670
+ } catch (error) {
671
+ await created.close().catch(() => {
672
+ });
673
+ throw error;
674
+ }
675
+ return created;
676
+ });
677
+ const entry = { browser, version, shownUpTo: time, page, queue: Promise.resolve() };
678
+ pages.set(url, entry);
679
+ while (pages.size > maxPages) drop(pages.keys().next().value);
680
+ return entry;
681
+ };
682
+ const armIdleClose = (url, entry) => {
683
+ if (pages.get(url) !== entry) return;
684
+ clearTimeout(entry.idleTimer);
685
+ entry.idleTimer = setTimeout(() => {
686
+ if (pages.get(url) === entry) drop(url);
687
+ }, idleMs);
688
+ entry.idleTimer.unref?.();
689
+ };
690
+ return {
691
+ async withPage(browser, url, version, time, load, use) {
692
+ const current = entryFor(browser, url, version, time, load);
693
+ clearTimeout(current.idleTimer);
694
+ const run = current.queue.then(async () => use(await current.page));
695
+ current.queue = run.catch(() => {
696
+ });
697
+ try {
698
+ return await run;
699
+ } catch (error) {
700
+ if (pages.get(url) === current) drop(url);
701
+ throw error;
702
+ } finally {
703
+ armIdleClose(url, current);
704
+ }
705
+ },
706
+ closeAll() {
707
+ for (const url of [...pages.keys()]) drop(url);
708
+ }
709
+ };
710
+ }
711
+
712
+ // src/server/studioServer.ts
713
+ var STUDIO_MANUAL_EDITS_PATH = ".hyperframes/studio-manual-edits.json";
714
+ var RENDER_SHUTDOWN_WAIT_MS = 2e3;
715
+ var IMMUTABLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
716
+ var REMOTE_GIF_IMG_SRC_RE = /<img\b[^>]*?\bsrc\s*=\s*["'](https?:\/\/[^"']+\.gif(?:[?#][^"']*)?)["'][^>]*>/gi;
717
+ async function loadStudioProducer() {
718
+ if (!isDevMode()) return await import("./src-JHQGB2S6.js");
719
+ if (!process.versions.bun) {
720
+ throw new Error(
721
+ "Studio dev-mode rendering requires bun (the producer is loaded from TypeScript source, which Node cannot resolve). Restart the studio with `bun run studio`."
722
+ );
723
+ }
724
+ return await import("./src-JHQGB2S6.js");
725
+ }
726
+ function resolveDistDir() {
727
+ return resolveStudioBundle().dir;
728
+ }
729
+ function resolveStudioBundle() {
730
+ const builtPath = resolve2(__dirname, "studio");
731
+ const builtIndex = resolve2(builtPath, "index.html");
732
+ if (existsSync2(builtIndex)) {
733
+ return { dir: builtPath, indexPath: builtIndex, available: true, checkedPaths: [builtIndex] };
734
+ }
735
+ const devPath = resolve2(__dirname, "..", "..", "..", "studio", "dist");
736
+ const devIndex = resolve2(devPath, "index.html");
737
+ if (existsSync2(devIndex)) {
738
+ return {
739
+ dir: devPath,
740
+ indexPath: devIndex,
741
+ available: true,
742
+ checkedPaths: [builtIndex, devIndex]
743
+ };
744
+ }
745
+ return {
746
+ dir: builtPath,
747
+ indexPath: builtIndex,
748
+ available: false,
749
+ checkedPaths: [builtIndex, devIndex]
750
+ };
751
+ }
752
+ function resolveRuntimePath() {
753
+ const builtPath = resolve2(__dirname, "hyperframe-runtime.js");
754
+ if (existsSync2(builtPath)) return builtPath;
755
+ const iifePath = resolve2(__dirname, "hyperframe.runtime.iife.js");
756
+ if (existsSync2(iifePath)) return iifePath;
757
+ const devPath = resolve2(
758
+ __dirname,
759
+ "..",
760
+ "..",
761
+ "..",
762
+ "core",
763
+ "dist",
764
+ "hyperframe.runtime.iife.js"
765
+ );
766
+ if (existsSync2(devPath)) return devPath;
767
+ return builtPath;
768
+ }
769
+ var GSAP_LOCAL_ROOT = "/api/vendor/npm";
770
+ var GSAP_VENDOR_FILES = /* @__PURE__ */ new Set(["gsap.min.js", "CustomEase.min.js", "MotionPathPlugin.min.js"]);
771
+ function installedGsapDist() {
772
+ try {
773
+ const coreRequire = createRequire(resolve2(__dirname, "..", "..", "..", "core", "package.json"));
774
+ return join2(dirname3(coreRequire.resolve("gsap/package.json")), "dist");
775
+ } catch {
776
+ return null;
777
+ }
778
+ }
779
+ function resolveGsapVendorDir() {
780
+ const vendored = join2("vendor", "npm", `gsap@${GSAP_CDN_VERSION}`, "dist");
781
+ const candidates = [
782
+ resolve2(__dirname, vendored),
783
+ // Running from source: the built CLI next door, then core's installed gsap.
784
+ resolve2(__dirname, "..", "..", "dist", vendored),
785
+ installedGsapDist()
786
+ ];
787
+ for (const dir of candidates) {
788
+ if (!dir) continue;
789
+ if (!existsSync2(join2(dir, "gsap.min.js"))) continue;
790
+ const manifest = readBundleFile(join2(dir, "..", "package.json"));
791
+ if (manifest && JSON.parse(manifest.toString("utf-8")).version !== GSAP_CDN_VERSION) continue;
792
+ return dir;
793
+ }
794
+ return null;
795
+ }
796
+ function readStudioManualEditManifestContent(projectDir) {
797
+ const manifestPath = join2(projectDir, STUDIO_MANUAL_EDITS_PATH);
798
+ if (!existsSync2(manifestPath)) return "";
799
+ try {
800
+ return readFileSync2(manifestPath, "utf-8");
801
+ } catch {
802
+ return "";
803
+ }
804
+ }
805
+ async function applyStudioManualEditsToThumbnailPage(page, manifestContent, activeCompositionPath) {
806
+ const script = createStudioManualEditsRenderBodyScript(manifestContent, {
807
+ activeCompositionPath
808
+ });
809
+ if (!script) return;
810
+ await page.addScriptTag({ content: script });
811
+ }
812
+ async function reapplyStudioManualEditsToThumbnailPage(page) {
813
+ await page.evaluate(() => {
814
+ const apply = window.__hfStudioManualEditsApply;
815
+ if (typeof apply === "function") apply();
816
+ });
817
+ }
818
+ function collectRemoteGifImageSources(html) {
819
+ const urls = /* @__PURE__ */ new Set();
820
+ const re = new RegExp(REMOTE_GIF_IMG_SRC_RE.source, REMOTE_GIF_IMG_SRC_RE.flags);
821
+ let match;
822
+ while ((match = re.exec(html)) !== null) {
823
+ if (match[1]) urls.add(match[1]);
824
+ }
825
+ return [...urls];
826
+ }
827
+ async function downloadRemoteGifImageSources(html, downloadDir, downloadToTemp) {
828
+ const sourceAssets = /* @__PURE__ */ new Map();
829
+ await Promise.all(
830
+ collectRemoteGifImageSources(html).map(async (url) => {
831
+ try {
832
+ sourceAssets.set(url, await downloadToTemp(url, downloadDir));
833
+ } catch (err) {
834
+ console.warn(
835
+ "[Studio] Remote animated GIF prep skipped:",
836
+ err instanceof Error ? err.message : err
837
+ );
838
+ }
839
+ })
840
+ );
841
+ return sourceAssets;
842
+ }
843
+ var _thumbnailBrowserLease = null;
844
+ var thumbnailPages = createThumbnailPages();
845
+ var _thumbnailBrowserInitializing = null;
846
+ var _thumbnailBrowserModes = null;
847
+ async function getThumbnailBrowser(requestedGpuMode, isShuttingDown) {
848
+ if (isShuttingDown()) return null;
849
+ if (_thumbnailBrowserLease?.browser.connected && _thumbnailBrowserModes?.requested === requestedGpuMode) {
850
+ return {
851
+ browser: _thumbnailBrowserLease.browser,
852
+ requestedGpuMode: _thumbnailBrowserModes.requested,
853
+ resolvedGpuMode: _thumbnailBrowserModes.resolved,
854
+ softwareWebGpu: _thumbnailBrowserModes.softwareWebGpu
855
+ };
856
+ }
857
+ if (_thumbnailBrowserInitializing) {
858
+ const session = await _thumbnailBrowserInitializing;
859
+ if (session?.requestedGpuMode === requestedGpuMode) return session;
860
+ }
861
+ if (_thumbnailBrowserLease) await closeThumbnailBrowser();
862
+ _thumbnailBrowserInitializing = (async () => {
863
+ try {
864
+ if (isShuttingDown()) return null;
865
+ const { ensureBrowser } = await import("./manager-CD6LJ7ZN.js");
866
+ const { acquireBrowser, buildChromeArgs } = await import("./src-Z5PGEMXB.js");
867
+ let executablePath;
868
+ try {
869
+ const b = await ensureBrowser({ preferManagedChrome: true });
870
+ executablePath = b.executablePath;
871
+ if (b.executablePath && !process.env.PRODUCER_HEADLESS_SHELL_PATH) {
872
+ process.env.PRODUCER_HEADLESS_SHELL_PATH = b.executablePath;
873
+ }
874
+ } catch {
875
+ }
876
+ const resolvedGpuMode = await resolveCaptureBrowserGpuMode(requestedGpuMode, executablePath);
877
+ const { gpuConfig, softwareWebGpu } = resolveLocalWebGpu(resolvedGpuMode, true);
878
+ const acquired = await acquireBrowser(
879
+ buildChromeArgs(
880
+ {
881
+ width: 1920,
882
+ height: 1080,
883
+ captureMode: "screenshot",
884
+ requiresWebGpu: softwareWebGpu
885
+ },
886
+ gpuConfig
887
+ ),
888
+ { forceScreenshot: true }
889
+ );
890
+ _thumbnailBrowserLease = acquired;
891
+ _thumbnailBrowserModes = {
892
+ requested: requestedGpuMode,
893
+ resolved: resolvedGpuMode,
894
+ softwareWebGpu
895
+ };
896
+ acquired.browser.on("disconnected", () => {
897
+ if (_thumbnailBrowserLease !== acquired) return;
898
+ _thumbnailBrowserLease = null;
899
+ _thumbnailBrowserModes = null;
900
+ _thumbnailBrowserInitializing = null;
901
+ });
902
+ return { browser: acquired.browser, requestedGpuMode, resolvedGpuMode, softwareWebGpu };
903
+ } catch (err) {
904
+ console.warn(
905
+ "[Studio] Failed to launch thumbnail browser:",
906
+ err instanceof Error ? err.message : err
907
+ );
908
+ _thumbnailBrowserInitializing = null;
909
+ return null;
910
+ }
911
+ })();
912
+ return _thumbnailBrowserInitializing;
913
+ }
914
+ async function closeThumbnailBrowser() {
915
+ thumbnailPages.closeAll();
916
+ if (_thumbnailBrowserInitializing) await _thumbnailBrowserInitializing.catch(() => {
917
+ });
918
+ if (!_thumbnailBrowserLease) return;
919
+ const lease = _thumbnailBrowserLease;
920
+ _thumbnailBrowserLease = null;
921
+ _thumbnailBrowserModes = null;
922
+ _thumbnailBrowserInitializing = null;
923
+ await lease.release().catch(() => {
924
+ });
925
+ }
926
+ async function loadPreviewServerBuildSignature() {
927
+ const runtimeSignature = await loadRuntimeSourceSignature();
928
+ const studioBundle = resolveStudioBundle();
929
+ const studioIndex = studioBundle.available ? readBundleFile(studioBundle.indexPath)?.toString("utf-8") ?? "" : "";
930
+ return hashSignatureParts([
931
+ VERSION,
932
+ runtimeSignature,
933
+ studioIndex,
934
+ createStudioServer.toString(),
935
+ createStudioApi.toString(),
936
+ createProjectSignature.toString(),
937
+ getMimeType.toString(),
938
+ getElementScreenshotClip.toString()
939
+ ]);
940
+ }
941
+ function rewriteWrittenToHostViewport(projectDir, written) {
942
+ const indexPath = join2(projectDir, "index.html");
943
+ if (!existsSync2(indexPath)) return;
944
+ const indexHtml = readFileSync2(indexPath, "utf-8");
945
+ const hostW = indexHtml.match(/data-width="(\d+)"/)?.[1];
946
+ const hostH = indexHtml.match(/data-height="(\d+)"/)?.[1];
947
+ if (!hostW || !hostH) return;
948
+ for (const absPath of written) {
949
+ if (!absPath.endsWith(".html")) continue;
950
+ let content = readFileSync2(absPath, "utf-8");
951
+ content = content.replace(
952
+ /(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+/i,
953
+ `$1${hostW}$2${hostH}`
954
+ );
955
+ content = content.replace(
956
+ /(\bwidth:\s*)\d+(px;\s*\n?\s*height:\s*)\d+(px;)/g,
957
+ (match, pre, mid, post) => {
958
+ if (match.includes("1920") || match.includes("1080")) {
959
+ return `${pre}${hostW}${mid}${hostH}${post}`;
960
+ }
961
+ return match;
962
+ }
963
+ );
964
+ replaceFileAtomically(absPath, content, statSync2(absPath).mode);
965
+ }
966
+ }
967
+ function createStudioServer(options) {
968
+ const { projectDir, projectName } = options;
969
+ const projectId = projectName || basename2(projectDir);
970
+ const browserGpuMode = options.browserGpuMode ?? resolveLocalBrowserGpuMode();
971
+ const studioDir = resolveDistDir();
972
+ const runtimePath = resolveRuntimePath();
973
+ const gsapVendorDir = resolveGsapVendorDir();
974
+ stampProjectHfIds(projectDir);
975
+ const watcher = createProjectWatcher(projectDir);
976
+ const project = { id: projectId, dir: projectDir, title: projectId };
977
+ let cachedProjectSignature = null;
978
+ watcher.addListener((changedPath) => {
979
+ if (changedPath === "." || affectsProjectSignature(projectDir, join2(projectDir, changedPath))) {
980
+ cachedProjectSignature = null;
981
+ }
982
+ });
983
+ const projectSignature = (dir) => {
984
+ if (resolve2(dir) !== resolve2(projectDir)) return createProjectSignature(dir);
985
+ cachedProjectSignature ??= createProjectSignature(projectDir);
986
+ return cachedProjectSignature;
987
+ };
988
+ let ownerWaitMs;
989
+ const historyUrl = () => {
990
+ const origin = options.origin?.();
991
+ return origin && `${origin}/api/projects/${encodeURIComponent(projectId)}/history`;
992
+ };
993
+ const histories = historyCache(
994
+ () => openProjectHistory({
995
+ projectDir,
996
+ historyRoot: options.historyRoot ?? DEFAULT_HISTORY_ROOT,
997
+ ownerWaitMs,
998
+ ownerUrl: historyUrl()
999
+ }).then((history) => {
1000
+ ownerWaitMs = void 0;
1001
+ return history;
1002
+ }).catch((error) => {
1003
+ console.warn(`[studio] Project history is off: ${String(error)}`);
1004
+ if (error instanceof HistoryBusyError) ownerWaitMs = 0;
1005
+ if (error instanceof HistoryBusyError || error instanceof HistoryClosedError)
1006
+ histories.forget(projectDir);
1007
+ return null;
1008
+ })
1009
+ );
1010
+ const projectHistory = () => histories.get(projectDir);
1011
+ watcher.addListener((changedPath) => {
1012
+ void histories.peek(projectDir)?.then((opened) => opened?.noteChange(changedPath));
1013
+ });
1014
+ const inFlightRenders = /* @__PURE__ */ new Map();
1015
+ let shuttingDown = false;
1016
+ const adapter = {
1017
+ history: () => projectHistory(),
1018
+ loadSharp: () => loadSharpInBackground("image thumbnails"),
1019
+ // Explicit option wins (preview's resolved --proxy/--no-proxy + config);
1020
+ // otherwise honor the project's hyperframes.json media.autoProxy so every
1021
+ // createStudioServer caller (e.g. the background preview child) gets the
1022
+ // configured behavior without its own plumbing.
1023
+ autoProxy: options.autoProxy ?? resolveAutoProxy(projectDir, void 0),
1024
+ listProjects: () => [project],
1025
+ // Salted with the running CLI file, so an upgraded CLI never serves an older build's document.
1026
+ previewDocuments: createPreviewDocumentStore(
1027
+ projectDir,
1028
+ createHash2("sha256").update(readFileSync2(fileURLToPath(import.meta.url))).digest("hex")
1029
+ ),
1030
+ resolveProject: (id) => id === projectId ? project : null,
1031
+ async bundle(dir, options2) {
1032
+ try {
1033
+ const { bundleToSingleHtml } = await import("./compiler-TM3W6GYF.js");
1034
+ let html = await bundleToSingleHtml(dir, { ...PREVIEW_BUNDLE_OPTIONS, ...options2 });
1035
+ html = html.replace(
1036
+ 'data-hyperframes-preview-runtime="1" src=""',
1037
+ 'data-hyperframes-preview-runtime="1" src="/api/runtime.js"'
1038
+ );
1039
+ return html;
1040
+ } catch (err) {
1041
+ console.error("[studio] Bundle failed:", err);
1042
+ return null;
1043
+ }
1044
+ },
1045
+ async transformPreviewHtml({ html, project: project2 }) {
1046
+ const { injectDeterministicFontFaces } = await import("./deterministicFonts-RADD3BSX.js");
1047
+ const { prepareAnimatedGifInputs } = await import("./animatedGifPrep-QPKGJ6PM.js");
1048
+ const { downloadToTemp, writeUrlDownloadTelemetry } = await import("./urlDownloader-H2LXLG4U.js");
1049
+ const gifOutputDir = join2(project2.dir, ".hyperframes", "prepared-assets", "gif");
1050
+ const gifDownloadDir = join2(project2.dir, ".hyperframes", "prepared-assets", "downloads");
1051
+ const prepared = await prepareAnimatedGifInputs(html, {
1052
+ projectDir: project2.dir,
1053
+ downloadDir: gifDownloadDir,
1054
+ outputDir: gifOutputDir,
1055
+ outputSrcPrefix: ".hyperframes/prepared-assets/gif",
1056
+ cacheDir: gifOutputDir,
1057
+ sourceAssets: await downloadRemoteGifImageSources(
1058
+ html,
1059
+ gifDownloadDir,
1060
+ (url, destDir) => downloadToTemp(url, destDir, void 0, void 0, void 0, {
1061
+ onTelemetry: writeUrlDownloadTelemetry
1062
+ })
1063
+ )
1064
+ });
1065
+ return injectDeterministicFontFaces(prepared.html);
1066
+ },
1067
+ getProjectSignature: projectSignature,
1068
+ invalidateProjectSignature: (dir) => {
1069
+ if (resolve2(dir) === resolve2(projectDir)) cachedProjectSignature = null;
1070
+ },
1071
+ async lint(html, opts) {
1072
+ const { lintHyperframeHtml } = await import("./dist-BE4B2EZE.js");
1073
+ return await lintHyperframeHtml(html, { ...opts, host: "studio" });
1074
+ },
1075
+ // Out of process: linting a large composition is seconds of synchronous parsing, and on
1076
+ // this event loop it stalls every other Studio request, the preview included.
1077
+ lintProject: (dir) => runRenderSetupWorker(
1078
+ "lint",
1079
+ { projectDir: dir, host: "studio" },
1080
+ { maxBufferBytes: 8 * 1024 * 1024 }
1081
+ ),
1082
+ runtimeUrl: "/api/runtime.js",
1083
+ gsapLocalRoot: gsapVendorDir ? GSAP_LOCAL_ROOT : void 0,
1084
+ rendersDir: () => join2(projectDir, "renders"),
1085
+ startRender(opts) {
1086
+ if (shuttingDown) {
1087
+ return {
1088
+ id: opts.jobId,
1089
+ status: "failed",
1090
+ progress: 0,
1091
+ outputPath: opts.outputPath,
1092
+ error: "Studio server is shutting down"
1093
+ };
1094
+ }
1095
+ refreshTelemetryPosture();
1096
+ const abortController = new AbortController();
1097
+ const state = {
1098
+ id: opts.jobId,
1099
+ status: "rendering",
1100
+ progress: 0,
1101
+ outputPath: opts.outputPath,
1102
+ cancel: () => abortController.abort()
1103
+ };
1104
+ const startTime = Date.now();
1105
+ const cpu = startRenderCpuSampler(opts.telemetryOptOut !== true);
1106
+ const run = (async () => {
1107
+ let renderJob;
1108
+ const removeCancelledOutput = () => {
1109
+ state.status = "cancelled";
1110
+ for (const suffix of ["", ".meta.json"]) {
1111
+ const fp = suffix ? opts.outputPath.replace(/\.(mp4|webm|mov)$/, suffix) : opts.outputPath;
1112
+ try {
1113
+ if (existsSync2(fp)) unlinkSync(fp);
1114
+ } catch {
1115
+ }
1116
+ }
1117
+ };
1118
+ try {
1119
+ const { createRenderJob, executeRenderJob } = await loadStudioProducer();
1120
+ const browser = await resolveRenderBrowser(abortController.signal);
1121
+ if (!process.env.PRODUCER_HEADLESS_SHELL_PATH) {
1122
+ process.env.PRODUCER_HEADLESS_SHELL_PATH = browser.executablePath;
1123
+ }
1124
+ const manifestContent = readStudioManualEditManifestContent(opts.project.dir);
1125
+ const manualEditsRenderScript = createStudioManualEditsRenderBodyScript(manifestContent);
1126
+ const job = createRenderJob({
1127
+ // opts.fps is already an Fps rational — see vite-config-studio
1128
+ // adapter for the same convention.
1129
+ fps: opts.fps,
1130
+ quality: opts.quality,
1131
+ format: opts.format,
1132
+ outputResolution: opts.outputResolution,
1133
+ ...manualEditsRenderScript ? { renderBodyScripts: [manualEditsRenderScript] } : {},
1134
+ ...opts.composition ? { entryFile: opts.composition } : {},
1135
+ ...opts.variables ? { variables: opts.variables } : {},
1136
+ ...opts.crf !== void 0 ? { crf: opts.crf } : {},
1137
+ ...opts.videoBitrate ? { videoBitrate: opts.videoBitrate } : {},
1138
+ ...opts.videoFrameFormat ? { videoFrameFormat: opts.videoFrameFormat } : {},
1139
+ ...opts.hdrMode ? { hdrMode: opts.hdrMode } : {},
1140
+ ...opts.useGpu ? { useGpu: true } : {},
1141
+ ...opts.pageMotionBlur ? { pageMotionBlur: opts.pageMotionBlur } : {}
1142
+ });
1143
+ renderJob = job;
1144
+ const onProgress = (j) => {
1145
+ state.progress = j.progress;
1146
+ if (j.currentStage) state.stage = j.currentStage;
1147
+ };
1148
+ await executeRenderJob(
1149
+ job,
1150
+ opts.project.dir,
1151
+ opts.outputPath,
1152
+ onProgress,
1153
+ abortController.signal
1154
+ );
1155
+ if (abortController.signal.aborted) {
1156
+ removeCancelledOutput();
1157
+ return;
1158
+ }
1159
+ if (job.audioLoweredDb !== void 0) state.audioLoweredDb = job.audioLoweredDb;
1160
+ state.status = "complete";
1161
+ state.progress = 100;
1162
+ const metaPath = opts.outputPath.replace(/\.(mp4|webm|mov)$/, ".meta.json");
1163
+ writeFileSync(
1164
+ metaPath,
1165
+ JSON.stringify({
1166
+ status: "complete",
1167
+ durationMs: Date.now() - startTime,
1168
+ ...job.audioLoweredDb !== void 0 ? { audioLoweredDb: job.audioLoweredDb } : {}
1169
+ })
1170
+ );
1171
+ refreshTelemetryPosture();
1172
+ emitStudioRenderComplete(opts, Date.now() - startTime, job.perfSummary, cpu.stop());
1173
+ } catch (err) {
1174
+ if (abortController.signal.aborted) {
1175
+ removeCancelledOutput();
1176
+ return;
1177
+ }
1178
+ state.status = "failed";
1179
+ state.error = err instanceof Error ? err.message : String(err);
1180
+ refreshTelemetryPosture();
1181
+ emitStudioRenderError(
1182
+ opts,
1183
+ Date.now() - startTime,
1184
+ state.stage,
1185
+ err,
1186
+ renderJob,
1187
+ cpu.stop()
1188
+ );
1189
+ try {
1190
+ const metaPath = opts.outputPath.replace(/\.(mp4|webm|mov)$/, ".meta.json");
1191
+ writeFileSync(metaPath, JSON.stringify({ status: "failed" }));
1192
+ } catch {
1193
+ }
1194
+ } finally {
1195
+ cpu.stop();
1196
+ }
1197
+ })();
1198
+ inFlightRenders.set(abortController, run);
1199
+ const forget = () => void inFlightRenders.delete(abortController);
1200
+ run.then(forget, forget);
1201
+ return state;
1202
+ },
1203
+ startBackgroundRemoval(opts) {
1204
+ return createBackgroundRemovalJob(opts, async (renderOpts) => {
1205
+ const sourcePipelinePath = "../background-removal/pipeline.ts";
1206
+ const pipeline = await import("./pipeline-VXIUYEBU.js").catch(
1207
+ () => import(sourcePipelinePath)
1208
+ );
1209
+ return pipeline.render(renderOpts);
1210
+ });
1211
+ },
1212
+ async generateThumbnail(opts) {
1213
+ const session = await getThumbnailBrowser(browserGpuMode, () => shuttingDown);
1214
+ if (!session) {
1215
+ if (!shuttingDown) {
1216
+ console.warn("[Studio] Thumbnail: no browser available \u2014 Chrome may not be installed");
1217
+ }
1218
+ return null;
1219
+ }
1220
+ const sourcePath = join2(opts.project.dir, opts.compPath);
1221
+ const requiresWebGpu = existsSync2(sourcePath) ? compositionRequiresWebGpu(readFileSync2(sourcePath, "utf-8")) : false;
1222
+ if (opts.signal.aborted) return null;
1223
+ const width = opts.width || 1920;
1224
+ const height = opts.height || 1080;
1225
+ const viewport = { width, height, deviceScaleFactor: thumbnailDeviceScaleFactor(opts) };
1226
+ try {
1227
+ return await thumbnailPages.withPage(
1228
+ session.browser,
1229
+ opts.previewUrl,
1230
+ projectSignature(opts.project.dir),
1231
+ opts.seekTime,
1232
+ async (page) => {
1233
+ await page.setViewport(viewport);
1234
+ await page.goto(opts.previewUrl, { waitUntil: "domcontentloaded", timeout: 1e4 });
1235
+ await assertWebGpuAdapterAvailable(
1236
+ page,
1237
+ requiresWebGpu,
1238
+ requiresWebGpu && session.softwareWebGpu
1239
+ );
1240
+ await page.waitForFunction(
1241
+ () => {
1242
+ const w = window;
1243
+ return !!(w.__timelines && Object.keys(w.__timelines).length > 0);
1244
+ },
1245
+ { timeout: 5e3 }
1246
+ ).catch(() => {
1247
+ });
1248
+ },
1249
+ async (page) => {
1250
+ if (opts.signal.aborted) return null;
1251
+ await page.setViewport(viewport);
1252
+ await seekCompositionTimeline(page, opts.seekTime, {
1253
+ fallbackToBridgeAndTimelines: true,
1254
+ waitForPreferredSeekTargetMs: 500,
1255
+ animationFrameSettle: "double",
1256
+ waitForFontsMs: 500
1257
+ });
1258
+ const manifestContent = readStudioManualEditManifestContent(opts.project.dir);
1259
+ await applyStudioManualEditsToThumbnailPage(page, manifestContent, opts.compPath);
1260
+ await page.evaluate(() => {
1261
+ void document.fonts?.ready;
1262
+ const body = document.body;
1263
+ if (body && getComputedStyle(body).backgroundColor === "rgba(0, 0, 0, 0)") {
1264
+ body.style.backgroundColor = "#1c2028";
1265
+ }
1266
+ });
1267
+ await new Promise((r) => setTimeout(r, 200));
1268
+ await reapplyStudioManualEditsToThumbnailPage(page);
1269
+ if (opts.signal.aborted) return null;
1270
+ try {
1271
+ const clip = opts.selector ? await page.evaluate(getElementScreenshotClip, opts.selector, opts.selectorIndex) : void 0;
1272
+ return await page.screenshot(
1273
+ opts.format === "png" ? { type: "png", ...clip ? { clip } : {} } : { type: "jpeg", quality: 80, ...clip ? { clip } : {} }
1274
+ );
1275
+ } finally {
1276
+ if (opts.selector) await page.evaluate(clearElementScreenshotIsolation);
1277
+ }
1278
+ }
1279
+ );
1280
+ } catch (err) {
1281
+ if (!opts.signal.aborted) {
1282
+ console.warn(
1283
+ "[Studio] Thumbnail generation failed:",
1284
+ err instanceof Error ? err.message : err
1285
+ );
1286
+ }
1287
+ return null;
1288
+ }
1289
+ },
1290
+ async listRegistryCatalog() {
1291
+ const { listRegistryItems, loadAllItems } = await import("./resolver-D5BIPSEW.js");
1292
+ const { loadProjectConfig } = await import("./projectConfig-3MZAYVTS.js");
1293
+ const registry = { baseUrl: loadProjectConfig(projectDir).registry };
1294
+ const entries = await listRegistryItems(void 0, registry);
1295
+ const blockAndComponentEntries = entries.filter(
1296
+ (e) => e.type === "hyperframes:block" || e.type === "hyperframes:component"
1297
+ );
1298
+ return loadAllItems(blockAndComponentEntries, registry);
1299
+ },
1300
+ async installRegistryBlock(opts) {
1301
+ const { addToProject, primaryInstalledTarget } = await import("./add-VMJD5KBS.js");
1302
+ const { recordRewrittenInstall } = await import("./installer-ML4HWUV7.js");
1303
+ const { registryTargetPath } = await import("./publication-DTKWNF74.js");
1304
+ const { result, item } = await addToProject({
1305
+ name: opts.blockName,
1306
+ projectDir: opts.project.dir,
1307
+ skipClipboard: true,
1308
+ source: "studio"
1309
+ });
1310
+ for (const warning of result.warnings) {
1311
+ process.stderr.write(`hyperframes:registry ${warning}
1312
+ `);
1313
+ }
1314
+ const written = result.written;
1315
+ rewriteWrittenToHostViewport(opts.project.dir, written);
1316
+ recordRewrittenInstall(opts.project.dir, written);
1317
+ const root = realpath(opts.project.dir);
1318
+ const primary = primaryInstalledTarget(item);
1319
+ const primaryPath = registryTargetPath(root, primary);
1320
+ const others = written.filter((abs) => abs !== primaryPath).map((abs) => relative2(root, abs).split(sep2).join("/"));
1321
+ return {
1322
+ written: written.includes(primaryPath) ? [primary, ...others] : others,
1323
+ block: item
1324
+ };
1325
+ }
1326
+ };
1327
+ const app = new Hono();
1328
+ app.get("/__hyperframes_config", (c) => {
1329
+ const serve = async () => {
1330
+ const serverBuildSignature = await loadPreviewServerBuildSignature();
1331
+ return c.json({
1332
+ isHyperframes: true,
1333
+ pid: process.pid,
1334
+ projectName: projectId,
1335
+ projectDir,
1336
+ serverBuildSignature,
1337
+ browserGpuMode,
1338
+ version: VERSION
1339
+ });
1340
+ };
1341
+ return serve();
1342
+ });
1343
+ app.get("/api/runtime.js", (c) => {
1344
+ const serve = async () => {
1345
+ const runtimeSource = await loadRuntimeSource() ?? readBundleFile(runtimePath)?.toString("utf-8") ?? null;
1346
+ if (!runtimeSource) return c.text("runtime not available", 404);
1347
+ return c.body(runtimeSource, 200, {
1348
+ "Content-Type": getMimeType("runtime.js"),
1349
+ "Cache-Control": "no-store"
1350
+ });
1351
+ };
1352
+ return serve();
1353
+ });
1354
+ app.get(`${GSAP_LOCAL_ROOT}/:pkg/dist/:file`, (c) => {
1355
+ const file = c.req.param("file");
1356
+ const body = gsapVendorDir && c.req.param("pkg") === `gsap@${GSAP_CDN_VERSION}` && GSAP_VENDOR_FILES.has(file) ? readBundleFile(join2(gsapVendorDir, file)) : null;
1357
+ if (!body) return c.text("not found", 404);
1358
+ return c.body(body, 200, {
1359
+ "Content-Type": getMimeType(file),
1360
+ "Cache-Control": "public, max-age=31536000, immutable"
1361
+ });
1362
+ });
1363
+ app.get("/api/telemetry-identity", (c) => {
1364
+ if (!identityAllowed(c.req.header("host"))) {
1365
+ return c.json({ error: "forbidden" }, 403);
1366
+ }
1367
+ refreshTelemetryPosture();
1368
+ return c.json({ distinctId: resolveCliTelemetryDistinctId() });
1369
+ });
1370
+ app.get("/api/events", (c) => {
1371
+ return streamSSE(c, async (stream) => {
1372
+ const listener = (path) => {
1373
+ const absPath = resolve2(projectDir, path);
1374
+ let version = null;
1375
+ try {
1376
+ version = fileContentVersion(readFileSync2(absPath));
1377
+ } catch {
1378
+ }
1379
+ const receipt = identifyFileWrite(absPath, version ?? DELETED_VERSION);
1380
+ const reloads = affectsPreview(projectDir, path);
1381
+ stream.writeSSE({
1382
+ event: "file-change",
1383
+ data: JSON.stringify({
1384
+ path,
1385
+ version,
1386
+ projectId: project.id,
1387
+ affectsPreview: reloads,
1388
+ // Which thumbnails this write can change; null means all of them.
1389
+ affectedCompositions: reloads ? compositionsAffectedBy(projectDir, path) : [],
1390
+ ...receipt
1391
+ })
1392
+ }).catch(() => {
1393
+ });
1394
+ };
1395
+ const wrappedListener = (changedPath) => {
1396
+ if (shouldWatchProjectFile(changedPath)) listener(changedPath);
1397
+ };
1398
+ watcher.addListener(wrappedListener);
1399
+ stream.onAbort(() => watcher.removeListener(wrappedListener));
1400
+ try {
1401
+ while (true) {
1402
+ await stream.sleep(3e4);
1403
+ }
1404
+ } finally {
1405
+ watcher.removeListener(wrappedListener);
1406
+ }
1407
+ });
1408
+ });
1409
+ let ffmpegReady = false;
1410
+ app.get("/api/environment/ffmpeg", async (c) => {
1411
+ if (ffmpegReady) return c.json({ ok: true });
1412
+ const [{ runEnvironmentChecks }, { getFFmpegInstallCommand }] = await Promise.all([
1413
+ import("./preflight-2KZ2GWAZ.js"),
1414
+ import("./ffmpeg-DR5LGGSK.js")
1415
+ ]);
1416
+ const { outcomes } = await runEnvironmentChecks();
1417
+ const failed = outcomes.find((outcome) => !outcome.ok);
1418
+ if (!failed) {
1419
+ ffmpegReady = true;
1420
+ return c.json({ ok: true });
1421
+ }
1422
+ return c.json({
1423
+ ok: false,
1424
+ title: failed.title ?? `${failed.name} not found`,
1425
+ detail: failed.detail,
1426
+ hint: failed.hint,
1427
+ command: getFFmpegInstallCommand()
1428
+ });
1429
+ });
1430
+ mountDesktopRoutes(app, projectDir);
1431
+ let cachedFFmpegPath;
1432
+ app.post("/api/projects/:id/render", async (c, next) => {
1433
+ const { findFFmpeg, getFFmpegInstallHint } = await import("./ffmpeg-DR5LGGSK.js");
1434
+ if (!cachedFFmpegPath) {
1435
+ cachedFFmpegPath = findFFmpeg();
1436
+ }
1437
+ if (!cachedFFmpegPath) {
1438
+ return c.json({ error: "FFmpeg not found", hint: getFFmpegInstallHint() }, 503);
1439
+ }
1440
+ return next();
1441
+ });
1442
+ const api = createStudioApi(adapter);
1443
+ app.all("/api/*", async (c) => {
1444
+ const url = new URL(c.req.url);
1445
+ url.pathname = url.pathname.slice(4);
1446
+ const forwardReq = new Request(url.toString(), {
1447
+ method: c.req.method,
1448
+ headers: c.req.raw.headers,
1449
+ body: c.req.raw.body,
1450
+ // @ts-expect-error -- Node needs duplex for streaming bodies
1451
+ duplex: "half"
1452
+ });
1453
+ return api.fetch(forwardReq);
1454
+ });
1455
+ const serveStudioStaticFile = (cacheControl) => (c) => {
1456
+ const filePath = resolve2(studioDir, c.req.path.slice(1));
1457
+ if (!isWithinProjectRoot(studioDir, filePath)) return c.text("not found", 404);
1458
+ const content = readBundleFile(filePath);
1459
+ if (content === null) return c.text("not found", 404);
1460
+ return new Response(content, {
1461
+ headers: { "Content-Type": getMimeType(filePath), "Cache-Control": cacheControl }
1462
+ });
1463
+ };
1464
+ app.get("/assets/*", serveStudioStaticFile(IMMUTABLE_CACHE_CONTROL));
1465
+ app.get("/icons/*", serveStudioStaticFile("no-store"));
1466
+ app.get("/favicon.svg", serveStudioStaticFile("no-store"));
1467
+ function buildRuntimeEnvScript() {
1468
+ const overrides = {};
1469
+ for (const [key, value] of Object.entries(process.env)) {
1470
+ if (key.startsWith("VITE_STUDIO_") && value !== void 0) {
1471
+ overrides[key] = value;
1472
+ }
1473
+ }
1474
+ if (Object.keys(overrides).length === 0) return "";
1475
+ return `<script>window.__HF_STUDIO_ENV__=${JSON.stringify(overrides)};</script>`;
1476
+ }
1477
+ app.get("*", (c) => {
1478
+ const indexPath = resolve2(studioDir, "index.html");
1479
+ const indexContent = readBundleFile(indexPath);
1480
+ if (indexContent === null) {
1481
+ return c.html(
1482
+ `<!doctype html>
1483
+ <html>
1484
+ <head>
1485
+ <meta charset="utf-8" />
1486
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
1487
+ <title>Framey Studio unavailable</title>
1488
+ <style>
1489
+ body {
1490
+ margin: 0;
1491
+ min-height: 100vh;
1492
+ display: grid;
1493
+ place-items: center;
1494
+ background: #0d0f14;
1495
+ color: #eef2f7;
1496
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
1497
+ }
1498
+ main {
1499
+ width: min(560px, calc(100vw - 48px));
1500
+ border: 1px solid rgba(255, 255, 255, 0.14);
1501
+ border-radius: 8px;
1502
+ padding: 28px;
1503
+ background: #151923;
1504
+ }
1505
+ h1 {
1506
+ margin: 0 0 12px;
1507
+ font-size: 22px;
1508
+ line-height: 1.2;
1509
+ }
1510
+ p {
1511
+ margin: 0 0 18px;
1512
+ color: #aab3c2;
1513
+ line-height: 1.5;
1514
+ }
1515
+ code {
1516
+ display: block;
1517
+ padding: 12px 14px;
1518
+ border-radius: 6px;
1519
+ background: #090b10;
1520
+ color: #8ff0c2;
1521
+ overflow-wrap: anywhere;
1522
+ }
1523
+ </style>
1524
+ </head>
1525
+ <body>
1526
+ <main>
1527
+ <h1>Studio bundle missing</h1>
1528
+ <p>The preview server started, but this CLI build does not contain the Studio assets.</p>
1529
+ <code>bun run build</code>
1530
+ </main>
1531
+ </body>
1532
+ </html>`,
1533
+ 500
1534
+ );
1535
+ }
1536
+ let html = indexContent.toString("utf-8");
1537
+ const headScript = buildStudioHeadScriptsForHost(buildRuntimeEnvScript(), c.req.header("host"));
1538
+ if (headScript) {
1539
+ html = html.replace("<head>", `<head>${headScript}`);
1540
+ }
1541
+ return c.html(html, 200, { "Cache-Control": "no-cache" });
1542
+ });
1543
+ const shutdown = async () => {
1544
+ shuttingDown = true;
1545
+ const closeHistory = histories.closeAll().catch(() => {
1546
+ });
1547
+ const renders = [...inFlightRenders];
1548
+ for (const [abortController] of renders) abortController.abort();
1549
+ const { killTrackedProcesses, closeBrowserPool } = await import("./src-Z5PGEMXB.js");
1550
+ killTrackedProcesses();
1551
+ const closeBrowsers = Promise.allSettled([
1552
+ closeThumbnailBrowser().catch(() => {
1553
+ }),
1554
+ closeBrowserPool().catch(() => {
1555
+ })
1556
+ ]);
1557
+ await Promise.race([
1558
+ Promise.allSettled([...renders.map(([, done]) => done), closeHistory]),
1559
+ new Promise((resolve3) => setTimeout(resolve3, RENDER_SHUTDOWN_WAIT_MS).unref())
1560
+ ]);
1561
+ await closeBrowsers;
1562
+ };
1563
+ return { app, watcher, adapter, shutdown };
1564
+ }
1565
+ export {
1566
+ createStudioServer,
1567
+ loadPreviewServerBuildSignature,
1568
+ resolveStudioBundle
1569
+ };