@vfrey/vfrey 0.0.1 → 1.0.0-beta.1

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 (610) 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 +361 -0
  40. package/src/api/cloud-files.ts +197 -0
  41. package/src/api/cloud-runs.ts +75 -0
  42. package/src/api/cloud.ts +413 -0
  43. package/src/api/commands.ts +330 -0
  44. package/src/api/config.ts +34 -0
  45. package/src/api/creators.ts +463 -0
  46. package/src/api/credentials.ts +152 -0
  47. package/src/api/mail.ts +333 -0
  48. package/src/api/topics.ts +207 -0
  49. package/src/api/types.ts +273 -0
  50. package/src/cli.ts +468 -0
  51. package/src/cloud/bundle.ts +70 -0
  52. package/src/cloud/cloudrun-executor.ts +237 -0
  53. package/src/cloud/executor.ts +281 -0
  54. package/src/cloud/gcs-sign.ts +76 -0
  55. package/src/cloud/job.ts +106 -0
  56. package/src/cloud/remote-job.ts +67 -0
  57. package/src/cloud/render-job.ts +191 -0
  58. package/src/config.ts +309 -0
  59. package/src/dashboard-link.ts +180 -0
  60. package/src/dashboard-start.ts +103 -0
  61. package/src/desk/channel.ts +64 -0
  62. package/src/desk/cli.ts +216 -0
  63. package/src/desk/creators-route.ts +129 -0
  64. package/src/desk/fonts/JetBrainsMono-OFL.txt +93 -0
  65. package/src/desk/fonts/google-sans-flex-latin.woff2 +0 -0
  66. package/src/desk/fonts/jetbrains-mono-medium.woff2 +0 -0
  67. package/src/desk/http.ts +460 -0
  68. package/src/desk/mail-route.ts +103 -0
  69. package/src/desk/overlay.ts +112 -0
  70. package/src/desk/preview.ts +422 -0
  71. package/src/desk/screens.ts +149 -0
  72. package/src/desk/secrets.ts +143 -0
  73. package/src/desk/series.ts +127 -0
  74. package/src/desk/state.ts +77 -0
  75. package/src/desk/studio-route.ts +119 -0
  76. package/src/desk/tick-runner.ts +66 -0
  77. package/src/desk/tick.ts +56 -0
  78. package/src/desk/topics-route.ts +41 -0
  79. package/src/desk/ui/app.css +505 -0
  80. package/src/desk/ui/app.js +185 -0
  81. package/src/desk/ui/apple-icon.png +0 -0
  82. package/src/desk/ui/components.js +79 -0
  83. package/src/desk/ui/core.js +156 -0
  84. package/src/desk/ui/favicon.ico +0 -0
  85. package/src/desk/ui/icon.svg +1 -0
  86. package/src/desk/ui/icons.js +49 -0
  87. package/src/desk/ui/index.html +41 -0
  88. package/src/desk/ui/metrics-math.d.ts +22 -0
  89. package/src/desk/ui/metrics-math.js +135 -0
  90. package/src/desk/ui/theme.js +5 -0
  91. package/src/desk/ui/views-creators.js +209 -0
  92. package/src/desk/ui/views-keys.js +114 -0
  93. package/src/desk/ui/views-mail.js +188 -0
  94. package/src/desk/ui/views-misc.js +123 -0
  95. package/src/desk/ui/views-review.js +119 -0
  96. package/src/desk/ui/views-runs.js +350 -0
  97. package/src/desk/ui/views-screens.js +163 -0
  98. package/src/desk/ui/views-series.js +318 -0
  99. package/src/desk/ui/views-topics.js +87 -0
  100. package/src/desk/verbs.ts +361 -0
  101. package/src/doctor.ts +212 -0
  102. package/src/drain.ts +14 -0
  103. package/src/engage/index.ts +217 -0
  104. package/src/generate/index.ts +110 -0
  105. package/src/generate/script.ts +152 -0
  106. package/src/generate/title.ts +78 -0
  107. package/src/help.ts +252 -0
  108. package/src/home.ts +45 -0
  109. package/src/llm/client.ts +177 -0
  110. package/src/log.ts +7 -0
  111. package/src/oauth/tokens.ts +189 -0
  112. package/src/oauth/vault.ts +72 -0
  113. package/src/pipeline/review.ts +642 -0
  114. package/src/pipeline/run.ts +443 -0
  115. package/src/pipeline/series-guard.ts +26 -0
  116. package/src/pipeline/source-fetch.ts +69 -0
  117. package/src/pipeline/stages.ts +728 -0
  118. package/src/pipeline/topics-source.ts +90 -0
  119. package/src/product/commands.ts +296 -0
  120. package/src/product/config-file.ts +38 -0
  121. package/src/product/engine-choice.ts +89 -0
  122. package/src/product/engines.ts +103 -0
  123. package/src/product/insights.ts +50 -0
  124. package/src/product/keys.ts +67 -0
  125. package/src/product/paths.ts +18 -0
  126. package/src/product/probes.ts +88 -0
  127. package/src/product/push-flow.ts +90 -0
  128. package/src/product/render-video.ts +21 -0
  129. package/src/product/short.ts +62 -0
  130. package/src/product/update.ts +32 -0
  131. package/src/project/canonical.ts +14 -0
  132. package/src/project/commands.ts +177 -0
  133. package/src/project/dashboard-status.ts +28 -0
  134. package/src/project/discover.ts +19 -0
  135. package/src/project/index-file.ts +73 -0
  136. package/src/project/marker.ts +92 -0
  137. package/src/project/migrate.ts +201 -0
  138. package/src/project/names.ts +27 -0
  139. package/src/project/notice.ts +16 -0
  140. package/src/project/open.ts +88 -0
  141. package/src/project/scaffold.ts +112 -0
  142. package/src/project/templates.ts +42 -0
  143. package/src/project/videos.ts +64 -0
  144. package/src/publish/facebook.ts +91 -0
  145. package/src/publish/index.ts +12 -0
  146. package/src/publish/instagram.ts +97 -0
  147. package/src/publish/rate.ts +62 -0
  148. package/src/publish/session.ts +242 -0
  149. package/src/publish/tiktok.ts +202 -0
  150. package/src/publish/youtube.ts +177 -0
  151. package/src/queue/desk-ops.ts +1170 -0
  152. package/src/queue/seal.ts +3 -0
  153. package/src/queue/store.ts +1006 -0
  154. package/src/remotion/AiLabel.tsx +26 -0
  155. package/src/remotion/Root.tsx +73 -0
  156. package/src/remotion/defaults.ts +26 -0
  157. package/src/remotion/films/claude/ClaudeFilm.tsx +1014 -0
  158. package/src/remotion/films/engine/EngineMark.tsx +17 -0
  159. package/src/remotion/films/rea/ReaShort.tsx +552 -0
  160. package/src/remotion/films/rea/drawings.tsx +907 -0
  161. package/src/remotion/films/rea/timing.ts +144 -0
  162. package/src/remotion/index.ts +4 -0
  163. package/src/remotion/templates/EditorialSplit.tsx +39 -0
  164. package/src/remotion/templates/KineticType.tsx +39 -0
  165. package/src/remotion/templates/SignalBoard.tsx +50 -0
  166. package/src/remotion/timing.ts +22 -0
  167. package/src/render/chrome.ts +78 -0
  168. package/src/render/engine-mark.ts +29 -0
  169. package/src/render/framey-template.ts +130 -0
  170. package/src/render/html-engine.ts +149 -0
  171. package/src/render/node-crypto-stub.ts +11 -0
  172. package/src/render/probe.ts +29 -0
  173. package/src/render/props.ts +17 -0
  174. package/src/render/vertical-short.ts +35 -0
  175. package/src/render/webpack.ts +33 -0
  176. package/src/render/worker.ts +65 -0
  177. package/src/scene/assets/fonts/TitanOne-OFL.txt +94 -0
  178. package/src/scene/assets/fonts/titan-one.woff2 +0 -0
  179. package/src/scene/assets/gsap/LICENSE.txt +8 -0
  180. package/src/scene/assets/gsap/gsap.min.js +11 -0
  181. package/src/scene/audio.ts +54 -0
  182. package/src/scene/blocks/LICENSE +190 -0
  183. package/src/scene/blocks/NOTICE +5 -0
  184. package/src/scene/blocks/bar-chart-race/bar-chart-race.html +585 -0
  185. package/src/scene/blocks/beat-freeze-cut/beat-freeze-cut.html +874 -0
  186. package/src/scene/blocks/camcorder-hud/camcorder-hud.html +164 -0
  187. package/src/scene/blocks/camera-dolly-zoom/camera-dolly-zoom.html +355 -0
  188. package/src/scene/blocks/code-diff/code-diff.html +817 -0
  189. package/src/scene/blocks/code-snippet-apple-terminal-pro/code-snippet-apple-terminal-pro.html +248 -0
  190. package/src/scene/blocks/code-typing/code-typing.html +764 -0
  191. package/src/scene/blocks/data-chart/data-chart.html +452 -0
  192. package/src/scene/blocks/flowchart-vertical/flowchart-vertical.html +454 -0
  193. package/src/scene/blocks/hw-scribble-transition/hw-scribble-transition.html +153 -0
  194. package/src/scene/blocks/index.json +824 -0
  195. package/src/scene/blocks/lt-accent-underline/lt-accent-underline.html +107 -0
  196. package/src/scene/blocks/lt-bold-block/lt-bold-block.html +109 -0
  197. package/src/scene/blocks/lt-clean-bar/lt-clean-bar.html +112 -0
  198. package/src/scene/blocks/lt-dark-card/lt-dark-card.html +111 -0
  199. package/src/scene/blocks/lt-kicker-name/lt-kicker-name.html +114 -0
  200. package/src/scene/blocks/lt-mask-reveal/lt-mask-reveal.html +120 -0
  201. package/src/scene/blocks/lt-neon-border/lt-neon-border.html +391 -0
  202. package/src/scene/blocks/lt-stack-bars/lt-stack-bars.html +109 -0
  203. package/src/scene/blocks/macos-notification/macos-notification.html +194 -0
  204. package/src/scene/blocks/mk-background/mk-background.html +236 -0
  205. package/src/scene/blocks/mk-callout-highlight/mk-callout-highlight.html +183 -0
  206. package/src/scene/blocks/mk-clone-wall-transition/mk-clone-wall-transition.html +226 -0
  207. package/src/scene/blocks/mk-line-graph/mk-line-graph.html +293 -0
  208. package/src/scene/blocks/mk-progress-stat/mk-progress-stat.html +186 -0
  209. package/src/scene/blocks/mk-specs-list/mk-specs-list.html +223 -0
  210. package/src/scene/blocks/news-ticker/news-ticker.html +409 -0
  211. package/src/scene/blocks/organic-light-leak-overlay/organic-light-leak-overlay.html +126 -0
  212. package/src/scene/blocks/oscilloscope-trace/oscilloscope-trace.html +519 -0
  213. package/src/scene/blocks/snow/snow.html +205 -0
  214. package/src/scene/blocks/split-flap-board/split-flap-board.html +347 -0
  215. package/src/scene/blocks/spotify-card/spotify-card.html +294 -0
  216. package/src/scene/blocks/starfield/starfield.html +188 -0
  217. package/src/scene/blocks/thread-message-stack/thread-message-stack.html +239 -0
  218. package/src/scene/blocks/week-in-merges/week-in-merges.html +470 -0
  219. package/src/scene/blocks/x-post/x-post.html +437 -0
  220. package/src/scene/blocks/yt-comment-card/yt-comment-card.html +319 -0
  221. package/src/scene/blocks/yt-lcd-background/yt-lcd-background.html +307 -0
  222. package/src/scene/blocks/yt-prism-title/yt-prism-title.html +205 -0
  223. package/src/scene/blocks.ts +229 -0
  224. package/src/scene/command.ts +272 -0
  225. package/src/scene/figure.ts +181 -0
  226. package/src/scene/glyphs.ts +107 -0
  227. package/src/scene/init.ts +86 -0
  228. package/src/scene/inspect/css-tree.d.ts +6 -0
  229. package/src/scene/inspect/page-scripts.ts +272 -0
  230. package/src/scene/inspect/report.ts +405 -0
  231. package/src/scene/inspect/run.ts +200 -0
  232. package/src/scene/inspect/source.ts +236 -0
  233. package/src/scene/label.ts +131 -0
  234. package/src/scene/net-guard.ts +74 -0
  235. package/src/scene/render.ts +292 -0
  236. package/src/scene/runtime/browser.ts +199 -0
  237. package/src/scene/runtime/core.ts +181 -0
  238. package/src/scene/runtime/react.tsx +115 -0
  239. package/src/scene/runtime/transitions.ts +133 -0
  240. package/src/scene/sanitize.ts +181 -0
  241. package/src/scene/scene.ts +152 -0
  242. package/src/scene/studio-command.ts +48 -0
  243. package/src/scene/studio-skin.ts +59 -0
  244. package/src/scene/studio.ts +337 -0
  245. package/src/scene/supply.ts +111 -0
  246. package/src/scene/timing.ts +288 -0
  247. package/src/scene/transitions/LICENSE +190 -0
  248. package/src/scene/transitions/NOTICE +5 -0
  249. package/src/scene/transitions/SOURCE.json +24 -0
  250. package/src/scene/transitions/transitions.global.js +38 -0
  251. package/src/scene/transitions.ts +26 -0
  252. package/src/service/all-projects.ts +153 -0
  253. package/src/service/commands.ts +256 -0
  254. package/src/service/due.ts +82 -0
  255. package/src/service/lock.ts +101 -0
  256. package/src/service/log-file.ts +56 -0
  257. package/src/service/state.ts +41 -0
  258. package/src/service/units.ts +90 -0
  259. package/src/service/worker.ts +51 -0
  260. package/src/skill-agents.ts +74 -0
  261. package/src/skill-install.ts +334 -0
  262. package/src/sync-write.ts +21 -0
  263. package/src/tick-report.ts +205 -0
  264. package/src/tts.ts +124 -0
  265. package/vendor/@vfrey/contracts/dist/account.d.ts +97 -0
  266. package/vendor/@vfrey/contracts/dist/account.js +27 -0
  267. package/vendor/@vfrey/contracts/dist/checks.d.ts +8 -0
  268. package/vendor/@vfrey/contracts/dist/checks.js +1 -0
  269. package/vendor/@vfrey/contracts/dist/credentials/crypto.d.ts +4 -0
  270. package/vendor/@vfrey/contracts/dist/credentials/crypto.js +38 -0
  271. package/vendor/@vfrey/contracts/dist/domain/advice-persona.d.ts +10 -0
  272. package/vendor/@vfrey/contracts/dist/domain/advice-persona.js +24 -0
  273. package/vendor/@vfrey/contracts/dist/domain/backoff.d.ts +13 -0
  274. package/vendor/@vfrey/contracts/dist/domain/backoff.js +27 -0
  275. package/vendor/@vfrey/contracts/dist/domain/cadence.d.ts +29 -0
  276. package/vendor/@vfrey/contracts/dist/domain/cadence.js +95 -0
  277. package/vendor/@vfrey/contracts/dist/domain/creators.d.ts +146 -0
  278. package/vendor/@vfrey/contracts/dist/domain/creators.js +2 -0
  279. package/vendor/@vfrey/contracts/dist/domain/disclosure.d.ts +127 -0
  280. package/vendor/@vfrey/contracts/dist/domain/disclosure.js +250 -0
  281. package/vendor/@vfrey/contracts/dist/domain/errors.d.ts +34 -0
  282. package/vendor/@vfrey/contracts/dist/domain/errors.js +68 -0
  283. package/vendor/@vfrey/contracts/dist/domain/redact.d.ts +1 -0
  284. package/vendor/@vfrey/contracts/dist/domain/redact.js +21 -0
  285. package/vendor/@vfrey/contracts/dist/domain/revenue.d.ts +13 -0
  286. package/vendor/@vfrey/contracts/dist/domain/revenue.js +16 -0
  287. package/vendor/@vfrey/contracts/dist/domain/safety.d.ts +20 -0
  288. package/vendor/@vfrey/contracts/dist/domain/safety.js +61 -0
  289. package/vendor/@vfrey/contracts/dist/domain/similarity.d.ts +13 -0
  290. package/vendor/@vfrey/contracts/dist/domain/similarity.js +100 -0
  291. package/vendor/@vfrey/contracts/dist/domain/templates.d.ts +18 -0
  292. package/vendor/@vfrey/contracts/dist/domain/templates.js +67 -0
  293. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.d.ts +19 -0
  294. package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.js +52 -0
  295. package/vendor/@vfrey/contracts/dist/domain/topics.d.ts +78 -0
  296. package/vendor/@vfrey/contracts/dist/domain/topics.js +4 -0
  297. package/vendor/@vfrey/contracts/dist/domain/types.d.ts +216 -0
  298. package/vendor/@vfrey/contracts/dist/domain/types.js +1 -0
  299. package/vendor/@vfrey/contracts/dist/domain/variation.d.ts +57 -0
  300. package/vendor/@vfrey/contracts/dist/domain/variation.js +278 -0
  301. package/vendor/@vfrey/contracts/dist/events.d.ts +20 -0
  302. package/vendor/@vfrey/contracts/dist/events.js +1 -0
  303. package/vendor/@vfrey/contracts/dist/http.d.ts +11 -0
  304. package/vendor/@vfrey/contracts/dist/http.js +37 -0
  305. package/vendor/@vfrey/contracts/dist/index.d.ts +22 -0
  306. package/vendor/@vfrey/contracts/dist/index.js +22 -0
  307. package/vendor/@vfrey/contracts/dist/log.d.ts +2 -0
  308. package/vendor/@vfrey/contracts/dist/log.js +10 -0
  309. package/vendor/@vfrey/contracts/dist/mail.d.ts +55 -0
  310. package/vendor/@vfrey/contracts/dist/mail.js +1 -0
  311. package/vendor/@vfrey/contracts/package.json +18 -0
  312. package/vendor/@vfrey/ingest/dist/index.d.ts +41 -0
  313. package/vendor/@vfrey/ingest/dist/index.js +221 -0
  314. package/vendor/@vfrey/ingest/dist/parse.d.ts +5 -0
  315. package/vendor/@vfrey/ingest/dist/parse.js +165 -0
  316. package/vendor/@vfrey/ingest/package.json +21 -0
  317. package/vendor/framey/LICENSE +190 -0
  318. package/vendor/framey/NOTICE +15 -0
  319. package/vendor/framey/SOURCE.json +24 -0
  320. package/vendor/framey/STUDIO-SOURCE.json +9 -0
  321. package/vendor/framey/bin/framey-localize-fonts.mjs +12 -0
  322. package/vendor/framey/bin/framey.mjs +16 -0
  323. package/vendor/framey/dist/add-VMJD5KBS.js +75 -0
  324. package/vendor/framey/dist/animatedGifPrep-QPKGJ6PM.js +43 -0
  325. package/vendor/framey/dist/api.d.ts +211 -0
  326. package/vendor/framey/dist/api.js +76 -0
  327. package/vendor/framey/dist/appHistory-WW56FZTT.js +31 -0
  328. package/vendor/framey/dist/asset-WQKGOELE.js +26 -0
  329. package/vendor/framey/dist/audio-RSJWVWRA.js +1936 -0
  330. package/vendor/framey/dist/batchRender-3HPICDCT.js +366 -0
  331. package/vendor/framey/dist/beats-HL2BDUZI.js +273 -0
  332. package/vendor/framey/dist/benchmark-RWCWHI5Z.js +230 -0
  333. package/vendor/framey/dist/browser-ECYET3Q2.js +206 -0
  334. package/vendor/framey/dist/bundleWithLocalizedFonts-ALYBQEQT.js +52 -0
  335. package/vendor/framey/dist/captureCompositionFrame-4DA6SEH2.js +94 -0
  336. package/vendor/framey/dist/catalog-5JVDEUWK.js +979 -0
  337. package/vendor/framey/dist/catch-up-NEBCL5NO.js +106 -0
  338. package/vendor/framey/dist/check-F5N544ML.js +111 -0
  339. package/vendor/framey/dist/checkBrowser-LZ66CMJG.js +110 -0
  340. package/vendor/framey/dist/chunk-2K7Z2HVP.js +372 -0
  341. package/vendor/framey/dist/chunk-2UZQHDM7.js +323 -0
  342. package/vendor/framey/dist/chunk-2X4PQEYM.js +34 -0
  343. package/vendor/framey/dist/chunk-3422KMTD.js +168 -0
  344. package/vendor/framey/dist/chunk-3FYD4YEK.js +72 -0
  345. package/vendor/framey/dist/chunk-3GXQPCJC.js +682 -0
  346. package/vendor/framey/dist/chunk-3LM6YPBR.js +179 -0
  347. package/vendor/framey/dist/chunk-442JNXRM.js +20 -0
  348. package/vendor/framey/dist/chunk-4BNN5FGX.js +182 -0
  349. package/vendor/framey/dist/chunk-4P7NX5BM.js +11532 -0
  350. package/vendor/framey/dist/chunk-4UMPIPCQ.js +88 -0
  351. package/vendor/framey/dist/chunk-4YYJOFKS.js +28 -0
  352. package/vendor/framey/dist/chunk-54HJ63Q2.js +29 -0
  353. package/vendor/framey/dist/chunk-5ETJX6WM.js +89 -0
  354. package/vendor/framey/dist/chunk-5SG54JRS.js +68 -0
  355. package/vendor/framey/dist/chunk-634HSJ3J.js +58 -0
  356. package/vendor/framey/dist/chunk-66LREXGS.js +48 -0
  357. package/vendor/framey/dist/chunk-6BEFEWFB.js +25 -0
  358. package/vendor/framey/dist/chunk-6BNTGNGD.js +286 -0
  359. package/vendor/framey/dist/chunk-6DDPOHMK.js +140 -0
  360. package/vendor/framey/dist/chunk-6GV5XSOR.js +214 -0
  361. package/vendor/framey/dist/chunk-6JR2XUEE.js +127 -0
  362. package/vendor/framey/dist/chunk-73QVATIM.js +362 -0
  363. package/vendor/framey/dist/chunk-7FMUTGOH.js +279 -0
  364. package/vendor/framey/dist/chunk-7JQFJ6JJ.js +291 -0
  365. package/vendor/framey/dist/chunk-AHPGAESX.js +113 -0
  366. package/vendor/framey/dist/chunk-AHX34EFP.js +15 -0
  367. package/vendor/framey/dist/chunk-AJ5CSAEZ.js +487 -0
  368. package/vendor/framey/dist/chunk-B7RJV74O.js +5047 -0
  369. package/vendor/framey/dist/chunk-BL4U6U52.js +254 -0
  370. package/vendor/framey/dist/chunk-BSQ7XANM.js +210 -0
  371. package/vendor/framey/dist/chunk-BZ56MTDX.js +6 -0
  372. package/vendor/framey/dist/chunk-C5BO7PMT.js +282 -0
  373. package/vendor/framey/dist/chunk-CFUCHO4T.js +358 -0
  374. package/vendor/framey/dist/chunk-CZGHFATT.js +31 -0
  375. package/vendor/framey/dist/chunk-DLA44CMS.js +5649 -0
  376. package/vendor/framey/dist/chunk-DPVXBVLL.js +31292 -0
  377. package/vendor/framey/dist/chunk-DQBY7FRR.js +397 -0
  378. package/vendor/framey/dist/chunk-EAMLBAHA.js +154 -0
  379. package/vendor/framey/dist/chunk-EOVYQ3IG.js +143 -0
  380. package/vendor/framey/dist/chunk-EVMY7IPL.js +612 -0
  381. package/vendor/framey/dist/chunk-FG4BBFZI.js +122 -0
  382. package/vendor/framey/dist/chunk-FI4I7CME.js +56 -0
  383. package/vendor/framey/dist/chunk-FLREUEHW.js +2081 -0
  384. package/vendor/framey/dist/chunk-FUFP7A7S.js +1126 -0
  385. package/vendor/framey/dist/chunk-FV3PIKGH.js +56 -0
  386. package/vendor/framey/dist/chunk-FXMKHHPO.js +123 -0
  387. package/vendor/framey/dist/chunk-GGZAM5VH.js +1187 -0
  388. package/vendor/framey/dist/chunk-GKZEVJIB.js +39 -0
  389. package/vendor/framey/dist/chunk-GMECXFAN.js +57 -0
  390. package/vendor/framey/dist/chunk-GNEFDLFB.js +621 -0
  391. package/vendor/framey/dist/chunk-GPMLSOEG.js +19274 -0
  392. package/vendor/framey/dist/chunk-GPYVT5EE.js +59 -0
  393. package/vendor/framey/dist/chunk-H6IEMZEV.js +40 -0
  394. package/vendor/framey/dist/chunk-HEFQCIXR.js +170 -0
  395. package/vendor/framey/dist/chunk-HFQ4CWHA.js +118 -0
  396. package/vendor/framey/dist/chunk-HPDTCOKE.js +304 -0
  397. package/vendor/framey/dist/chunk-HTUHQKDB.js +548 -0
  398. package/vendor/framey/dist/chunk-HU2SPFNG.js +103 -0
  399. package/vendor/framey/dist/chunk-HVW7ABXD.js +19 -0
  400. package/vendor/framey/dist/chunk-IG7NDKXO.js +26 -0
  401. package/vendor/framey/dist/chunk-II3J3WXK.js +246 -0
  402. package/vendor/framey/dist/chunk-IR35BCLK.js +13 -0
  403. package/vendor/framey/dist/chunk-ISN5GRYI.js +20 -0
  404. package/vendor/framey/dist/chunk-IUONB55J.js +669 -0
  405. package/vendor/framey/dist/chunk-IVSUQR2B.js +161 -0
  406. package/vendor/framey/dist/chunk-IXU6PQSW.js +259 -0
  407. package/vendor/framey/dist/chunk-IZCW2NKT.js +29 -0
  408. package/vendor/framey/dist/chunk-JGXJU5PF.js +68 -0
  409. package/vendor/framey/dist/chunk-JHOCK3DG.js +27 -0
  410. package/vendor/framey/dist/chunk-JVBRJMOP.js +121 -0
  411. package/vendor/framey/dist/chunk-K4MJX7SR.js +17 -0
  412. package/vendor/framey/dist/chunk-K4WKGXRC.js +18 -0
  413. package/vendor/framey/dist/chunk-KGPLIH7B.js +127 -0
  414. package/vendor/framey/dist/chunk-KLIKCX6Q.js +63 -0
  415. package/vendor/framey/dist/chunk-KXTKKBOC.js +61 -0
  416. package/vendor/framey/dist/chunk-KZI44OPA.js +185 -0
  417. package/vendor/framey/dist/chunk-LEKZNRKI.js +45 -0
  418. package/vendor/framey/dist/chunk-LFGJWOVA.js +61 -0
  419. package/vendor/framey/dist/chunk-LLMSX6V6.js +17 -0
  420. package/vendor/framey/dist/chunk-LTGTN2TH.js +195 -0
  421. package/vendor/framey/dist/chunk-M2WBOQ2Q.js +54 -0
  422. package/vendor/framey/dist/chunk-MI5FTLYK.js +399 -0
  423. package/vendor/framey/dist/chunk-MLQP2QUF.js +1809 -0
  424. package/vendor/framey/dist/chunk-MMQ52NIZ.js +956 -0
  425. package/vendor/framey/dist/chunk-ND46XKK3.js +742 -0
  426. package/vendor/framey/dist/chunk-NYEXNSHM.js +504 -0
  427. package/vendor/framey/dist/chunk-O4YRB27L.js +57 -0
  428. package/vendor/framey/dist/chunk-O7BGSQ5F.js +92 -0
  429. package/vendor/framey/dist/chunk-OFQWTKPW.js +117 -0
  430. package/vendor/framey/dist/chunk-P5ZBLXJ6.js +91 -0
  431. package/vendor/framey/dist/chunk-P6LJ4Y32.js +4662 -0
  432. package/vendor/framey/dist/chunk-PKZ7RK5N.js +281 -0
  433. package/vendor/framey/dist/chunk-PURHAXFL.js +15 -0
  434. package/vendor/framey/dist/chunk-Q5X2B5WT.js +29 -0
  435. package/vendor/framey/dist/chunk-QAMKOG67.js +248 -0
  436. package/vendor/framey/dist/chunk-R6YBK4XX.js +514 -0
  437. package/vendor/framey/dist/chunk-RGLQURIX.js +2997 -0
  438. package/vendor/framey/dist/chunk-RNV3DM4S.js +3573 -0
  439. package/vendor/framey/dist/chunk-ROEW726S.js +4638 -0
  440. package/vendor/framey/dist/chunk-RQVDTPGD.js +6 -0
  441. package/vendor/framey/dist/chunk-RVZHGOGR.js +26 -0
  442. package/vendor/framey/dist/chunk-RXATE6FZ.js +385 -0
  443. package/vendor/framey/dist/chunk-S3S4TGEH.js +424 -0
  444. package/vendor/framey/dist/chunk-SDYDNHEE.js +11202 -0
  445. package/vendor/framey/dist/chunk-SSWBU67I.js +173 -0
  446. package/vendor/framey/dist/chunk-ST35C4K6.js +28 -0
  447. package/vendor/framey/dist/chunk-SZNTYTIV.js +990 -0
  448. package/vendor/framey/dist/chunk-T2EUWCJE.js +29 -0
  449. package/vendor/framey/dist/chunk-T6AGUTZJ.js +444 -0
  450. package/vendor/framey/dist/chunk-THJALHFJ.js +11131 -0
  451. package/vendor/framey/dist/chunk-TIQB63MX.js +18128 -0
  452. package/vendor/framey/dist/chunk-U242RTCT.js +134 -0
  453. package/vendor/framey/dist/chunk-UJZREAV6.js +3901 -0
  454. package/vendor/framey/dist/chunk-UMD3V7CU.js +264 -0
  455. package/vendor/framey/dist/chunk-UOFAE5RF.js +42 -0
  456. package/vendor/framey/dist/chunk-UTEIUGAZ.js +29 -0
  457. package/vendor/framey/dist/chunk-VAS6HQX3.js +138 -0
  458. package/vendor/framey/dist/chunk-VC76R6W2.js +27 -0
  459. package/vendor/framey/dist/chunk-VFZ7W5W7.js +226 -0
  460. package/vendor/framey/dist/chunk-VHNLZAE2.js +348 -0
  461. package/vendor/framey/dist/chunk-VMC4WSH5.js +278 -0
  462. package/vendor/framey/dist/chunk-VORQIH64.js +108 -0
  463. package/vendor/framey/dist/chunk-VTXFRIHO.js +186 -0
  464. package/vendor/framey/dist/chunk-W2LGJSEN.js +182 -0
  465. package/vendor/framey/dist/chunk-WKBM7NDG.js +32 -0
  466. package/vendor/framey/dist/chunk-WMQNIQDJ.js +2057 -0
  467. package/vendor/framey/dist/chunk-WN4XZC5F.js +504 -0
  468. package/vendor/framey/dist/chunk-WQ6ZXHFQ.js +133 -0
  469. package/vendor/framey/dist/chunk-X7HBSTCZ.js +53 -0
  470. package/vendor/framey/dist/chunk-X7MTZ4T2.js +6 -0
  471. package/vendor/framey/dist/chunk-XPTOJZJF.js +308 -0
  472. package/vendor/framey/dist/chunk-XT6MXC7A.js +6 -0
  473. package/vendor/framey/dist/chunk-XT7X6QCP.js +6 -0
  474. package/vendor/framey/dist/chunk-XTMDWNEC.js +2820 -0
  475. package/vendor/framey/dist/chunk-XUHOIDKG.js +6 -0
  476. package/vendor/framey/dist/chunk-XX7LTW5Y.js +138 -0
  477. package/vendor/framey/dist/chunk-Y3YGTZEG.js +382 -0
  478. package/vendor/framey/dist/chunk-Y5SBSGN7.js +346 -0
  479. package/vendor/framey/dist/chunk-YCMVI4MZ.js +625 -0
  480. package/vendor/framey/dist/chunk-YOR4CTCE.js +261 -0
  481. package/vendor/framey/dist/chunk-YPRBGITP.js +2748 -0
  482. package/vendor/framey/dist/chunk-ZKDMAOFU.js +32 -0
  483. package/vendor/framey/dist/chunk-ZW6DURPF.js +1318 -0
  484. package/vendor/framey/dist/clean-ZJOGDKDM.js +336 -0
  485. package/vendor/framey/dist/cli.js +439 -0
  486. package/vendor/framey/dist/cloudrun-HGJ3B6ZV.js +767 -0
  487. package/vendor/framey/dist/commands/contrast-audit.browser.js +643 -0
  488. package/vendor/framey/dist/commands/layout-audit.browser.js +2914 -0
  489. package/vendor/framey/dist/commands/motion-sample.browser.js +74 -0
  490. package/vendor/framey/dist/commands/motion-signature.browser.js +475 -0
  491. package/vendor/framey/dist/compare-W7UY3BAZ.js +463 -0
  492. package/vendor/framey/dist/compiler-TM3W6GYF.js +136 -0
  493. package/vendor/framey/dist/component-QF5VGYMU.js +176 -0
  494. package/vendor/framey/dist/compositions-XT3PMNDF.js +238 -0
  495. package/vendor/framey/dist/contactSheet-7W6GYHBQ.js +24 -0
  496. package/vendor/framey/dist/deploy-6FJPWKF2.js +299 -0
  497. package/vendor/framey/dist/destroy-HE2RIPKZ.js +57 -0
  498. package/vendor/framey/dist/deterministicFonts-RADD3BSX.js +50 -0
  499. package/vendor/framey/dist/dist-4S2FGGVY.js +422 -0
  500. package/vendor/framey/dist/dist-BE4B2EZE.js +32 -0
  501. package/vendor/framey/dist/dist-EWXJGN63.js +129 -0
  502. package/vendor/framey/dist/docs-VKIRFEEX.js +131 -0
  503. package/vendor/framey/dist/doctor-2UNJ2G7U.js +74 -0
  504. package/vendor/framey/dist/dom-37K6YOH4.js +14 -0
  505. package/vendor/framey/dist/dotEnv-7PZQTVIM.js +54 -0
  506. package/vendor/framey/dist/events-ACY3P2PA.js +76 -0
  507. package/vendor/framey/dist/events-IHB3B2MK.js +69 -0
  508. package/vendor/framey/dist/ffmpeg-DR5LGGSK.js +63 -0
  509. package/vendor/framey/dist/figma-BODVUPHB.js +63 -0
  510. package/vendor/framey/dist/fontData.generated-NXAOI4GH.js +13 -0
  511. package/vendor/framey/dist/fontLocalizeCli.js +142 -0
  512. package/vendor/framey/dist/gpuPolicy-XLEXORZY.js +49 -0
  513. package/vendor/framey/dist/grade-compare-GAXFQ74C.js +661 -0
  514. package/vendor/framey/dist/gsapParser-IEUSLYDJ.js +2885 -0
  515. package/vendor/framey/dist/gsapParserAcorn-LZJKCFQI.js +30 -0
  516. package/vendor/framey/dist/help-VCB5X2HS.js +184 -0
  517. package/vendor/framey/dist/history-ENGZEVFT.js +471 -0
  518. package/vendor/framey/dist/hyperframe.manifest.json +22 -0
  519. package/vendor/framey/dist/hyperframe.runtime.iife.js +1132 -0
  520. package/vendor/framey/dist/hyperframes-player.global.js +478 -0
  521. package/vendor/framey/dist/hyperframes-slideshow.global.js +148 -0
  522. package/vendor/framey/dist/info-WPCJHBMU.js +182 -0
  523. package/vendor/framey/dist/init-G4WGLYGD.js +1176 -0
  524. package/vendor/framey/dist/inspect-5IQ6CNEQ.js +106 -0
  525. package/vendor/framey/dist/installer-ML4HWUV7.js +40 -0
  526. package/vendor/framey/dist/keyframes-Q6XJO7VW.js +2755 -0
  527. package/vendor/framey/dist/lambda-A7JC74JF.js +468 -0
  528. package/vendor/framey/dist/layout-YET6XNXA.js +95 -0
  529. package/vendor/framey/dist/lint-I7FZN2VJ.js +162 -0
  530. package/vendor/framey/dist/lintProject-PDB3UN72.js +30 -0
  531. package/vendor/framey/dist/manager-CD6LJ7ZN.js +45 -0
  532. package/vendor/framey/dist/manager-WA4F2GST.js +67 -0
  533. package/vendor/framey/dist/media-treatment-BXYS4WVA.js +1030 -0
  534. package/vendor/framey/dist/media-use-LWH3MANK.js +113 -0
  535. package/vendor/framey/dist/models-K363FYM4.js +195 -0
  536. package/vendor/framey/dist/motionShot-GPAVWXLH.js +640 -0
  537. package/vendor/framey/dist/normalize-FASIPBUM.js +24 -0
  538. package/vendor/framey/dist/normalize-audio-VDWYRHN6.js +268 -0
  539. package/vendor/framey/dist/open-E3TB6P6J.js +128 -0
  540. package/vendor/framey/dist/parakeetRunner-UP34UOI2.js +58 -0
  541. package/vendor/framey/dist/pipeline-VXIUYEBU.js +64 -0
  542. package/vendor/framey/dist/play-BUTDQ4DV.js +353 -0
  543. package/vendor/framey/dist/policies-OLDYGFK5.js +309 -0
  544. package/vendor/framey/dist/preflight-2KZ2GWAZ.js +55 -0
  545. package/vendor/framey/dist/present-GXYSM7NX.js +353 -0
  546. package/vendor/framey/dist/preview-EKZ33JOJ.js +1910 -0
  547. package/vendor/framey/dist/producer-SKU5EV3J.js +13 -0
  548. package/vendor/framey/dist/progress-ZWB4Z4ET.js +76 -0
  549. package/vendor/framey/dist/projectConfig-3MZAYVTS.js +60 -0
  550. package/vendor/framey/dist/publication-DTKWNF74.js +33 -0
  551. package/vendor/framey/dist/remove-background-OY5L7XN2.js +265 -0
  552. package/vendor/framey/dist/render-CDV4GDFX.js +187 -0
  553. package/vendor/framey/dist/render-YE5YAMOD.js +2620 -0
  554. package/vendor/framey/dist/render-batch-ZAMFPCLL.js +274 -0
  555. package/vendor/framey/dist/renderSetupWorker.js +120 -0
  556. package/vendor/framey/dist/resolver-D5BIPSEW.js +42 -0
  557. package/vendor/framey/dist/runtimeVersion.js +18 -0
  558. package/vendor/framey/dist/sam-WFZXI4F7.js +23 -0
  559. package/vendor/framey/dist/shaderTransitionWorker.js +44 -0
  560. package/vendor/framey/dist/sherpa-RQWLV7I3.js +79 -0
  561. package/vendor/framey/dist/sherpaWorker.js +84 -0
  562. package/vendor/framey/dist/sites-AMOVABTK.js +54 -0
  563. package/vendor/framey/dist/skill-ZHVLH7KX.js +15 -0
  564. package/vendor/framey/dist/slideshow-SJGK4RQS.js +24 -0
  565. package/vendor/framey/dist/snapshot-TUXL6LBQ.js +1515 -0
  566. package/vendor/framey/dist/src-JHQGB2S6.js +215 -0
  567. package/vendor/framey/dist/src-Z5PGEMXB.js +532 -0
  568. package/vendor/framey/dist/state-B6H3WHCF.js +28 -0
  569. package/vendor/framey/dist/staticProjectServer-DFVZOUGI.js +63 -0
  570. package/vendor/framey/dist/studio/assets/hyperframes-player-DLaKjw0L.js +478 -0
  571. package/vendor/framey/dist/studio/assets/index-BX3KHhGX.js +71 -0
  572. package/vendor/framey/dist/studio/assets/index-CYbvOVp-.css +1 -0
  573. package/vendor/framey/dist/studio/assets/index-Dp3QEUGL.js +402 -0
  574. package/vendor/framey/dist/studio/assets/index-qrTAXbqc.js +531 -0
  575. package/vendor/framey/dist/studio/favicon.svg +14 -0
  576. package/vendor/framey/dist/studio/icons/timeline/audio.svg +7 -0
  577. package/vendor/framey/dist/studio/icons/timeline/captions.svg +5 -0
  578. package/vendor/framey/dist/studio/icons/timeline/composition.svg +12 -0
  579. package/vendor/framey/dist/studio/icons/timeline/image.svg +18 -0
  580. package/vendor/framey/dist/studio/icons/timeline/music.svg +10 -0
  581. package/vendor/framey/dist/studio/icons/timeline/text.svg +3 -0
  582. package/vendor/framey/dist/studio/index.html +23 -0
  583. package/vendor/framey/dist/studio-api-2NECGRMB.js +179 -0
  584. package/vendor/framey/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
  585. package/vendor/framey/dist/studioServer-N2OPUMOQ.js +1569 -0
  586. package/vendor/framey/dist/synthesize-PKTB5ATG.js +183 -0
  587. package/vendor/framey/dist/system-7F3UEHQT.js +27 -0
  588. package/vendor/framey/dist/telemetry-DQGPEKM6.js +145 -0
  589. package/vendor/framey/dist/telemetry-UN55N6U6.js +77 -0
  590. package/vendor/framey/dist/timeline-LHUUMK63.js +1295 -0
  591. package/vendor/framey/dist/tokens-OLECWDFK.js +92 -0
  592. package/vendor/framey/dist/transcribe-O7HQKMIV.js +331 -0
  593. package/vendor/framey/dist/transcribe-UJESPBT5.js +76 -0
  594. package/vendor/framey/dist/tts-YCCQHZD4.js +234 -0
  595. package/vendor/framey/dist/urlDownloader-H2LXLG4U.js +48 -0
  596. package/vendor/framey/dist/usage-HG4WMM7A.js +2167 -0
  597. package/vendor/framey/dist/validate-F2XMN6EV.js +87 -0
  598. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/GSAP-LICENSE.txt +8 -0
  599. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/CustomEase.min.js +11 -0
  600. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/MotionPathPlugin.min.js +11 -0
  601. package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/gsap.min.js +11 -0
  602. package/vendor/framey/dist/warmCheck.js +220 -0
  603. package/vendor/framey/dist/warmCheckClient.js +139 -0
  604. package/vendor/framey/dist/workspaceBuildCheck-XYD2YTFW.js +133 -0
  605. package/vendor/framey-player/LICENSE +190 -0
  606. package/vendor/framey-player/NOTICE +16 -0
  607. package/vendor/framey-player/SOURCE.json +6 -0
  608. package/vendor/framey-player/hyperframes-player.global.js +478 -0
  609. package/vendor/framey.pin +1 -0
  610. package/bin/index.js +0 -3
@@ -0,0 +1,742 @@
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
+ runCancellableProcess,
9
+ runRenderSetupWorker
10
+ } from "./chunk-BL4U6U52.js";
11
+ import {
12
+ normalizeErrorMessage
13
+ } from "./chunk-T2EUWCJE.js";
14
+ import {
15
+ getFreeDiskMb
16
+ } from "./chunk-T6AGUTZJ.js";
17
+ import {
18
+ browserPathFromEnv,
19
+ managedChromeVersion,
20
+ pickSharedShell
21
+ } from "./chunk-4UMPIPCQ.js";
22
+
23
+ // src/browser/manager.ts
24
+ import { execSync, spawnSync } from "child_process";
25
+ import { randomUUID } from "crypto";
26
+ import {
27
+ existsSync,
28
+ mkdirSync,
29
+ readFileSync,
30
+ readdirSync,
31
+ renameSync,
32
+ rmSync,
33
+ statSync,
34
+ utimesSync,
35
+ writeFileSync
36
+ } from "fs";
37
+ import { homedir } from "os";
38
+ import { basename, dirname as dirname2, join, relative } from "path";
39
+
40
+ // src/browser/installProtocol.ts
41
+ var PROGRESS_PREFIX = "HYPERFRAMES_BROWSER_INSTALL_PROGRESS:";
42
+ var LOG_PREFIX = "HYPERFRAMES_BROWSER_INSTALL_LOG:";
43
+ function installProgressLine(downloaded, total) {
44
+ return `${PROGRESS_PREFIX}${JSON.stringify([downloaded, total])}
45
+ `;
46
+ }
47
+ function installLogLine(text) {
48
+ return `${LOG_PREFIX}${JSON.stringify(text)}
49
+ `;
50
+ }
51
+ function parseInstallLine(line) {
52
+ try {
53
+ if (line.startsWith(PROGRESS_PREFIX)) {
54
+ const [downloaded, total] = JSON.parse(line.slice(PROGRESS_PREFIX.length));
55
+ return { kind: "progress", downloaded, total };
56
+ }
57
+ if (line.startsWith(LOG_PREFIX)) {
58
+ return { kind: "log", text: JSON.parse(line.slice(LOG_PREFIX.length)) };
59
+ }
60
+ } catch {
61
+ }
62
+ return null;
63
+ }
64
+
65
+ // src/browser/installInChild.ts
66
+ var CHILD_STARTUP_MS = 15e3;
67
+ var BrowserDownloadStalledError = class extends Error {
68
+ };
69
+ function lineReader(onLine) {
70
+ let pending = "";
71
+ return (chunk) => {
72
+ const lines = (pending + chunk).split("\n");
73
+ pending = lines.pop() ?? "";
74
+ for (const line of lines) onLine(line);
75
+ };
76
+ }
77
+ async function installInChild(input, hooks) {
78
+ const abort = new AbortController();
79
+ let timer;
80
+ const arm = (waitMs) => {
81
+ clearTimeout(timer);
82
+ timer = setTimeout(
83
+ () => abort.abort(
84
+ new BrowserDownloadStalledError(
85
+ `The Chrome download from ${hooks.host} stalled: no data for ${hooks.stallMs / 1e3}s.`
86
+ )
87
+ ),
88
+ waitMs
89
+ );
90
+ timer.unref();
91
+ };
92
+ const onStdout = lineReader((line) => {
93
+ const event = parseInstallLine(line);
94
+ if (event?.kind === "log") hooks.onLog(event.text);
95
+ if (event?.kind !== "progress") return;
96
+ if (event.total > 0) hooks.onProgress?.(event.downloaded, event.total);
97
+ if (event.total > 0 && event.downloaded >= event.total) clearTimeout(timer);
98
+ else arm(hooks.stallMs);
99
+ });
100
+ arm(CHILD_STARTUP_MS + hooks.stallMs);
101
+ try {
102
+ return await runRenderSetupWorker("browser-install", input, {
103
+ signal: abort.signal,
104
+ detached: false,
105
+ maxBufferBytes: 4 * 1024 * 1024,
106
+ onStdout
107
+ });
108
+ } finally {
109
+ clearTimeout(timer);
110
+ }
111
+ }
112
+
113
+ // src/browser/unzipArchive.ts
114
+ import { mkdir } from "fs/promises";
115
+ import { dirname } from "path";
116
+ var UNZIP_DISK_FULL_STATUS = 50;
117
+ async function unzipArchive(archivePath, folderPath) {
118
+ await mkdir(dirname(folderPath), { recursive: true });
119
+ try {
120
+ await runCancellableProcess("unzip", ["-q", "-o", archivePath, "-d", folderPath], {
121
+ detached: false
122
+ });
123
+ return true;
124
+ } catch (err) {
125
+ if (err.code === "ENOENT") return false;
126
+ if (err.status === UNZIP_DISK_FULL_STATUS) {
127
+ throw new Error(
128
+ "Extraction failed: the disk filled up while unpacking Chrome. Free disk space, then retry.",
129
+ { cause: err }
130
+ );
131
+ }
132
+ const said = err.stderr?.trim();
133
+ throw new Error(`Extraction failed: ${said || err.message}`, { cause: err });
134
+ }
135
+ }
136
+
137
+ // src/browser/manager.ts
138
+ async function loadPuppeteerBrowsers() {
139
+ try {
140
+ return await import("@puppeteer/browsers");
141
+ } catch (err) {
142
+ const cause = normalizeErrorMessage(err);
143
+ throw new Error(
144
+ `Failed to load @puppeteer/browsers: ${cause}
145
+ Fix: run \`npm install\` or \`bun install\` to restore missing packages, then retry.`
146
+ );
147
+ }
148
+ }
149
+ var CACHE_ROOT_DIR = join(homedir(), ".cache", "hyperframes");
150
+ var CACHE_DIR = join(homedir(), ".cache", "hyperframes", "chrome");
151
+ var ARCHIVE_PLUS_UNPACKED_SHELL_MB = 512;
152
+ var PUPPETEER_CACHE_DIR = join(homedir(), ".cache", "puppeteer", "chrome-headless-shell");
153
+ var INSTALL_LOCK_DIR = join(CACHE_ROOT_DIR, ".chrome.install.lock");
154
+ var INSTALL_RECLAIM_LOCK_DIR = join(CACHE_ROOT_DIR, ".chrome.install.reclaim.lock");
155
+ var INSTALL_LOCK_OWNER_FILE = join(INSTALL_LOCK_DIR, "owner");
156
+ var INSTALL_LOCK_OWNER_ENV = "HYPERFRAMES_BROWSER_LOCK_OWNER";
157
+ var ownedInstallLockToken;
158
+ var INSTALL_LOCK_TIMINGS = {
159
+ staleMs: 12e4,
160
+ pollMs: 200,
161
+ heartbeatMs: 15e3,
162
+ waitNoticeMs: 1e4
163
+ };
164
+ function isErrno(err, code) {
165
+ return err.code === code;
166
+ }
167
+ function sleep(ms) {
168
+ return new Promise((resolve) => setTimeout(resolve, ms));
169
+ }
170
+ function tryAcquireDirLock(lockDir) {
171
+ try {
172
+ mkdirSync(lockDir, { recursive: false });
173
+ return true;
174
+ } catch (err) {
175
+ if (!isErrno(err, "EEXIST")) throw err;
176
+ return false;
177
+ }
178
+ }
179
+ function isDirLockStale(lockDir, timeoutMs) {
180
+ try {
181
+ return Date.now() - statSync(lockDir).mtimeMs > timeoutMs;
182
+ } catch (err) {
183
+ if (isErrno(err, "ENOENT")) return false;
184
+ throw err;
185
+ }
186
+ }
187
+ function reclaimStaleInstallLock(timeoutMs) {
188
+ if (!tryAcquireDirLock(INSTALL_RECLAIM_LOCK_DIR)) return;
189
+ try {
190
+ const mtimeMs = statSync(INSTALL_LOCK_DIR).mtimeMs;
191
+ if (Date.now() - mtimeMs > timeoutMs) {
192
+ rmSync(INSTALL_LOCK_DIR, { recursive: true, force: true });
193
+ }
194
+ } catch (err) {
195
+ if (!isErrno(err, "ENOENT")) throw err;
196
+ } finally {
197
+ rmSync(INSTALL_RECLAIM_LOCK_DIR, { recursive: true, force: true });
198
+ }
199
+ }
200
+ function reclaimAbandonedReclaimLock(timeoutMs) {
201
+ try {
202
+ if (isDirLockStale(INSTALL_RECLAIM_LOCK_DIR, timeoutMs)) {
203
+ rmSync(INSTALL_RECLAIM_LOCK_DIR, { recursive: true, force: true });
204
+ }
205
+ } catch (err) {
206
+ if (!isErrno(err, "ENOENT")) throw err;
207
+ }
208
+ }
209
+ function touchInstallLock() {
210
+ try {
211
+ const now = /* @__PURE__ */ new Date();
212
+ utimesSync(INSTALL_LOCK_DIR, now, now);
213
+ } catch {
214
+ }
215
+ }
216
+ async function withInstallLock(fn, timings = INSTALL_LOCK_TIMINGS) {
217
+ if (!existsSync(CACHE_ROOT_DIR)) mkdirSync(CACHE_ROOT_DIR, { recursive: true });
218
+ let deadline = Date.now() + timings.staleMs;
219
+ const waitStart = Date.now();
220
+ let lastNoticeMs = 0;
221
+ for (; ; ) {
222
+ if (existsSync(INSTALL_RECLAIM_LOCK_DIR)) {
223
+ reclaimAbandonedReclaimLock(timings.staleMs);
224
+ await sleep(timings.pollMs);
225
+ continue;
226
+ }
227
+ if (tryAcquireDirLock(INSTALL_LOCK_DIR)) {
228
+ ownedInstallLockToken = process.env[INSTALL_LOCK_OWNER_ENV] ?? randomUUID();
229
+ try {
230
+ writeFileSync(INSTALL_LOCK_OWNER_FILE, ownedInstallLockToken);
231
+ } catch (error) {
232
+ ownedInstallLockToken = void 0;
233
+ rmSync(INSTALL_LOCK_DIR, { recursive: true, force: true });
234
+ throw error;
235
+ }
236
+ rmSync(INSTALL_RECLAIM_LOCK_DIR, { recursive: true, force: true });
237
+ break;
238
+ }
239
+ const waitedMs = Date.now() - waitStart;
240
+ if (waitedMs - lastNoticeMs >= timings.waitNoticeMs) {
241
+ lastNoticeMs = waitedMs;
242
+ console.warn(
243
+ `[browser] Waiting for another framey process to finish installing chrome-headless-shell (${Math.round(waitedMs / 1e3)}s elapsed)...`
244
+ );
245
+ }
246
+ if (isDirLockStale(INSTALL_LOCK_DIR, timings.staleMs) || Date.now() > deadline) {
247
+ reclaimStaleInstallLock(timings.staleMs);
248
+ deadline = Date.now() + timings.staleMs;
249
+ continue;
250
+ }
251
+ await sleep(timings.pollMs);
252
+ }
253
+ const heartbeat = setInterval(touchInstallLock, timings.heartbeatMs);
254
+ if (typeof heartbeat.unref === "function") heartbeat.unref();
255
+ try {
256
+ return await fn();
257
+ } finally {
258
+ clearInterval(heartbeat);
259
+ releaseOwnedBrowserInstallLock();
260
+ }
261
+ }
262
+ function releaseOwnedBrowserInstallLock() {
263
+ if (!ownedInstallLockToken) return;
264
+ releaseBrowserInstallLock(ownedInstallLockToken);
265
+ }
266
+ function releaseBrowserInstallLock(ownerToken) {
267
+ if (ownedInstallLockToken === ownerToken) ownedInstallLockToken = void 0;
268
+ try {
269
+ if (readFileSync(INSTALL_LOCK_OWNER_FILE, "utf8") !== ownerToken) return;
270
+ } catch {
271
+ return;
272
+ }
273
+ rmSync(INSTALL_LOCK_DIR, { recursive: true, force: true });
274
+ }
275
+ var SYSTEM_CHROME_PATHS = process.platform === "darwin" ? ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"] : process.platform === "win32" ? [
276
+ join(
277
+ process.env["ProgramW6432"] ?? process.env["PROGRAMFILES"] ?? "C:\\Program Files",
278
+ "Google",
279
+ "Chrome",
280
+ "Application",
281
+ "chrome.exe"
282
+ ),
283
+ join(
284
+ process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)",
285
+ "Google",
286
+ "Chrome",
287
+ "Application",
288
+ "chrome.exe"
289
+ ),
290
+ ...process.env["LOCALAPPDATA"] ? [join(process.env["LOCALAPPDATA"], "Google", "Chrome", "Application", "chrome.exe")] : []
291
+ ] : [
292
+ "/usr/bin/google-chrome",
293
+ "/usr/bin/google-chrome-stable",
294
+ "/usr/bin/chromium",
295
+ "/usr/bin/chromium-browser"
296
+ ];
297
+ function whichBinary(name) {
298
+ try {
299
+ const cmd = process.platform === "win32" ? `where ${name}` : `which ${name}`;
300
+ const output = execSync(cmd, {
301
+ encoding: "utf-8",
302
+ stdio: ["pipe", "pipe", "pipe"],
303
+ timeout: 5e3,
304
+ windowsHide: true
305
+ });
306
+ const first = output.split(/\r?\n/).map((s) => s.trim()).find(Boolean);
307
+ return first || void 0;
308
+ } catch {
309
+ return void 0;
310
+ }
311
+ }
312
+ function findFromEnv() {
313
+ const envPath = browserPathFromEnv()?.path;
314
+ if (envPath && existsSync(envPath)) {
315
+ return { executablePath: envPath, source: "env" };
316
+ }
317
+ return void 0;
318
+ }
319
+ async function findFromHyperframesCache() {
320
+ if (!existsSync(CACHE_DIR)) return {};
321
+ const { Browser, detectBrowserPlatform, getInstalledBrowsers } = await loadPuppeteerBrowsers();
322
+ let installed;
323
+ try {
324
+ installed = await getInstalledBrowsers({ cacheDir: CACHE_DIR });
325
+ } catch (err) {
326
+ const code = err?.code;
327
+ const suffix = code ? ` (${code})` : "";
328
+ console.warn(
329
+ `[hyperframes] Browser cache read failed${suffix}: ${normalizeErrorMessage(err)}. Falling back to system Chrome or a fresh download.`
330
+ );
331
+ installed = [];
332
+ }
333
+ const hostPlatform = detectBrowserPlatform();
334
+ const match = installed.find(
335
+ (b) => b.browser === Browser.CHROMEHEADLESSSHELL && b.buildId === managedChromeVersion() && b.platform === hostPlatform
336
+ );
337
+ if (match && isUsableExecutable(match.executablePath)) {
338
+ return { result: { executablePath: match.executablePath, source: "cache" } };
339
+ }
340
+ if (match) {
341
+ return { staleHyperframesCachePath: match.executablePath };
342
+ }
343
+ return {};
344
+ }
345
+ async function findFromCache() {
346
+ const ours = await findFromHyperframesCache();
347
+ if (ours.result) return ours;
348
+ const fromPuppeteer = findFromPuppeteerCache();
349
+ return fromPuppeteer ? { result: fromPuppeteer } : ours;
350
+ }
351
+ var CACHED_HEADLESS_SHELL_EXECUTABLES = {
352
+ "darwin/arm64": ["chrome-headless-shell-mac-arm64", "chrome-headless-shell"],
353
+ "darwin/x64": ["chrome-headless-shell-mac-x64", "chrome-headless-shell"],
354
+ "linux/x64": ["chrome-headless-shell-linux64", "chrome-headless-shell"],
355
+ "win32/ia32": ["chrome-headless-shell-win32", "chrome-headless-shell.exe"],
356
+ "win32/x64": ["chrome-headless-shell-win64", "chrome-headless-shell.exe"]
357
+ };
358
+ function cachedHeadlessShellExecutable(hostPlatform = process.platform, hostArch = process.arch) {
359
+ return CACHED_HEADLESS_SHELL_EXECUTABLES[`${hostPlatform}/${hostArch}`];
360
+ }
361
+ function findFromPuppeteerCache() {
362
+ if (!existsSync(PUPPETEER_CACHE_DIR)) return void 0;
363
+ const executable = cachedHeadlessShellExecutable();
364
+ if (!executable) return void 0;
365
+ let versions;
366
+ try {
367
+ versions = readdirSync(PUPPETEER_CACHE_DIR);
368
+ } catch {
369
+ return void 0;
370
+ }
371
+ const binary = pickSharedShell(versions, (version) => {
372
+ const candidate = join(PUPPETEER_CACHE_DIR, version, ...executable);
373
+ return isUsableExecutable(candidate) ? candidate : void 0;
374
+ });
375
+ return binary ? { executablePath: binary, source: "cache" } : void 0;
376
+ }
377
+ function isHeadlessShellBinary(executablePath) {
378
+ const name = basename(executablePath).toLowerCase();
379
+ return name === "chrome-headless-shell" || name === "chrome-headless-shell.exe";
380
+ }
381
+ var _warnedSystemFallback = false;
382
+ function warnSystemFallbackOnce(executablePath) {
383
+ if (_warnedSystemFallback) return;
384
+ if (process.platform !== "linux") return;
385
+ if (isHeadlessShellBinary(executablePath)) return;
386
+ _warnedSystemFallback = true;
387
+ console.warn(
388
+ `[hyperframes] Using system Chrome at ${executablePath}; HeadlessExperimental.beginFrame is unavailable in regular Chrome builds, so the perf-optimized capture path falls back to screenshot mode. Install chrome-headless-shell for the optimized path:
389
+ npx @puppeteer/browsers install chrome-headless-shell
390
+ (Or set HYPERFRAMES_BROWSER_PATH to point at an existing chrome-headless-shell binary.)`
391
+ );
392
+ }
393
+ function _resetSystemFallbackWarnForTests() {
394
+ _warnedSystemFallback = false;
395
+ }
396
+ function findSystemBrowser() {
397
+ for (const p of SYSTEM_CHROME_PATHS) {
398
+ if (existsSync(p)) {
399
+ return { executablePath: p, source: "system" };
400
+ }
401
+ }
402
+ const fromWhich = whichBinary("google-chrome") ?? whichBinary("chromium");
403
+ if (fromWhich) {
404
+ return { executablePath: fromWhich, source: "system" };
405
+ }
406
+ return void 0;
407
+ }
408
+ async function findBrowser() {
409
+ const fromEnv = findFromEnv();
410
+ if (fromEnv) return fromEnv;
411
+ const fromCache = await findFromCache();
412
+ if (fromCache.result) return fromCache.result;
413
+ if (fromCache.staleHyperframesCachePath) {
414
+ console.warn(
415
+ `[browser] Cached binary unusable (missing, empty or not a file) at ${fromCache.staleHyperframesCachePath} \u2014 re-downloading...`
416
+ );
417
+ try {
418
+ return await withInstallLock(() => downloadBrowser());
419
+ } catch (err) {
420
+ const cause = normalizeErrorMessage(err);
421
+ throw new Error(
422
+ `Cached Chrome binary was unusable at ${fromCache.staleHyperframesCachePath}, and re-download failed: ${cause}
423
+ Run \`framey browser ensure --force\` to re-download.`
424
+ );
425
+ }
426
+ }
427
+ const fromSystem = findSystemBrowser();
428
+ if (fromSystem) {
429
+ warnSystemFallbackOnce(fromSystem.executablePath);
430
+ }
431
+ return fromSystem;
432
+ }
433
+ async function ensureLinuxArmBrowser(options) {
434
+ void options;
435
+ const existing = await findBrowser();
436
+ if (existing) return existing;
437
+ const hasApt = existsSync("/usr/bin/apt-get");
438
+ if (hasApt) {
439
+ console.error(
440
+ "\n\u{1F50D} Linux ARM64 detected \u2014 Chrome Headless Shell is not available for this platform."
441
+ );
442
+ console.error("\u{1F4E6} Auto-installing system Chromium via apt-get (this only happens once)...\n");
443
+ const result = spawnSync("apt-get", ["install", "-y", "chromium-browser"], {
444
+ stdio: "inherit",
445
+ timeout: 12e4
446
+ });
447
+ if (result.status === 0) {
448
+ const afterInstall = await findBrowser();
449
+ if (afterInstall) {
450
+ console.error(`
451
+ \u2705 Chromium installed at ${afterInstall.executablePath}
452
+ `);
453
+ return afterInstall;
454
+ }
455
+ } else {
456
+ console.error("\n\u26A0\uFE0F apt-get exited with errors. Trying anyway...\n");
457
+ const afterAttempt = await findBrowser();
458
+ if (afterAttempt) return afterAttempt;
459
+ }
460
+ }
461
+ throw new Error(
462
+ `Chrome Headless Shell is not available for Linux ARM64 (DGX Spark, GB10, Jetson).
463
+
464
+ Install Chromium manually and point framey to it:
465
+
466
+ sudo apt-get install -y chromium-browser
467
+ export HYPERFRAMES_BROWSER_PATH=$(which chromium-browser)
468
+
469
+ Then re-run your command. The HYPERFRAMES_BROWSER_PATH env var persists for the session.`
470
+ );
471
+ }
472
+ async function ensureBrowser(options) {
473
+ if (options?.signal) return ensureBrowserInOwnedProcess(options);
474
+ return ensureBrowserInCurrentProcess(options);
475
+ }
476
+ async function ensureBrowserInCurrentProcess(options) {
477
+ const fromEnv = findFromEnv();
478
+ if (fromEnv) return fromEnv;
479
+ if (!options?.force) {
480
+ const fromCache = await (options?.preferManagedChrome ? findFromHyperframesCache() : findFromCache());
481
+ if (fromCache.result) return fromCache.result;
482
+ if (fromCache.staleHyperframesCachePath) {
483
+ console.warn(
484
+ `[browser] Cached binary unusable (missing, empty or not a file) at ${fromCache.staleHyperframesCachePath} \u2014 re-downloading...`
485
+ );
486
+ return withInstallLock(() => downloadBrowser(options));
487
+ }
488
+ if (!options?.preferManagedChrome) {
489
+ const fromSystem = findSystemBrowser();
490
+ if (fromSystem) {
491
+ warnSystemFallbackOnce(fromSystem.executablePath);
492
+ return fromSystem;
493
+ }
494
+ }
495
+ }
496
+ return withInstallLock(async () => {
497
+ if (!options?.force) {
498
+ const afterLock = await (options?.preferManagedChrome ? findFromHyperframesCache() : findFromCache());
499
+ if (afterLock.result) return afterLock.result;
500
+ }
501
+ return downloadBrowser(options);
502
+ });
503
+ }
504
+ async function ensureBrowserInOwnedProcess(options) {
505
+ const signal = options.signal;
506
+ signal?.throwIfAborted();
507
+ const lockOwner = randomUUID();
508
+ try {
509
+ return await runRenderSetupWorker(
510
+ "browser",
511
+ {
512
+ force: options.force,
513
+ preferManagedChrome: options.preferManagedChrome
514
+ },
515
+ {
516
+ signal,
517
+ maxBufferBytes: 4 * 1024 * 1024,
518
+ env: { [INSTALL_LOCK_OWNER_ENV]: lockOwner }
519
+ }
520
+ );
521
+ } finally {
522
+ releaseBrowserInstallLock(lockOwner);
523
+ }
524
+ }
525
+ function isCorruptArchiveError(err) {
526
+ const msg = normalizeErrorMessage(err).toLowerCase();
527
+ return msg.includes("end of central directory") || msg.includes("end-of-central-directory") || msg.includes("invalid or corrupt") || msg.includes("corrupt zip") || msg.includes("not a zip") || msg.includes("unexpected end of") || msg.includes("corrupted");
528
+ }
529
+ async function installWithCorruptArchiveRecovery(runInstall, clearCache, onRecover) {
530
+ try {
531
+ return await runInstall();
532
+ } catch (err) {
533
+ if (!isCorruptArchiveError(err)) throw err;
534
+ onRecover?.(err);
535
+ clearCache();
536
+ return await runInstall();
537
+ }
538
+ }
539
+ function browserPathHintForPlatform() {
540
+ if (process.platform === "darwin") {
541
+ return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
542
+ }
543
+ if (process.platform === "win32") {
544
+ return "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";
545
+ }
546
+ return "/usr/bin/google-chrome";
547
+ }
548
+ function wrapDownloadFailureWithBrowserPathHint(cause, unzipLog) {
549
+ const original = normalizeErrorMessage(cause);
550
+ const unzipErrors = unzipLog.length > 0 ? ` Unzip errors: ${unzipLog.join("; ")}` : "";
551
+ const example = browserPathHintForPlatform();
552
+ const message = `Failed to install chrome-headless-shell ${managedChromeVersion()}: ${original}${unzipErrors}
553
+
554
+ Point framey at an already-installed Chrome/Chromium instead:
555
+
556
+ export HYPERFRAMES_BROWSER_PATH="${example}"
557
+
558
+ Then re-run your command. Any Chrome build works for the screenshot capture path; install a real chrome-headless-shell later if you need the perf-optimized BeginFrame path. Alternatively, run inside the framey Docker image which ships a compatible headless-shell.`;
559
+ return new Error(message, { cause: cause instanceof Error ? cause : void 0 });
560
+ }
561
+ var DOWNLOAD_STALL_MS = 6e4;
562
+ var DOWNLOAD_ATTEMPTS = 3;
563
+ async function retryOnStall(run, clear) {
564
+ for (let attempt = 1; ; attempt++) {
565
+ try {
566
+ return await run();
567
+ } catch (err) {
568
+ if (!(err instanceof BrowserDownloadStalledError) || attempt >= DOWNLOAD_ATTEMPTS) throw err;
569
+ console.warn(`[hyperframes] ${err.message} Retrying (${attempt}/${DOWNLOAD_ATTEMPTS - 1}).`);
570
+ clear();
571
+ }
572
+ }
573
+ }
574
+ function downloadHostOf(browsers, platform, buildId, baseUrl) {
575
+ try {
576
+ const url = browsers.getDownloadUrl(
577
+ browsers.Browser.CHROMEHEADLESSSHELL,
578
+ platform,
579
+ buildId,
580
+ baseUrl
581
+ );
582
+ return new URL(url).host;
583
+ } catch {
584
+ return "the Chrome download host";
585
+ }
586
+ }
587
+ function assertRoomToDownload() {
588
+ removeInstallLeftovers();
589
+ const freeMb = getFreeDiskMb(CACHE_ROOT_DIR);
590
+ if (freeMb !== null && freeMb < ARCHIVE_PLUS_UNPACKED_SHELL_MB) {
591
+ throw new Error(
592
+ `Low disk space: Chrome Headless Shell needs about ${ARCHIVE_PLUS_UNPACKED_SHELL_MB} MB to download, ${freeMb} MB free at ${CACHE_ROOT_DIR}. Free disk space, then retry.`
593
+ );
594
+ }
595
+ }
596
+ function stagedInstaller(browsers, platform, stagingDir, options, unzipLog) {
597
+ const buildId = managedChromeVersion();
598
+ const hooks = {
599
+ stallMs: options?.downloadStallMs ?? DOWNLOAD_STALL_MS,
600
+ host: downloadHostOf(browsers, platform, buildId, options?.downloadBaseUrl),
601
+ onProgress: options?.onProgress,
602
+ onLog: (line) => unzipLog.lines.push(line)
603
+ };
604
+ return async () => {
605
+ unzipLog.lines = [];
606
+ const input = {
607
+ cacheDir: stagingDir,
608
+ browser: browsers.Browser.CHROMEHEADLESSSHELL,
609
+ buildId,
610
+ platform,
611
+ baseUrl: options?.downloadBaseUrl
612
+ };
613
+ const unzipMayAskOnInput = process.platform !== "win32";
614
+ if (unzipMayAskOnInput) {
615
+ const archive = await installInChild({ ...input, unpack: false }, hooks);
616
+ const into = new browsers.Cache(stagingDir).installationDir(input.browser, platform, buildId);
617
+ await unzipArchive(archive, into);
618
+ }
619
+ return installInChild(input, hooks);
620
+ };
621
+ }
622
+ async function downloadBrowser(options) {
623
+ if (isLinuxArm()) {
624
+ return ensureLinuxArmBrowser(options);
625
+ }
626
+ assertRoomToDownload();
627
+ const browsers = await loadPuppeteerBrowsers();
628
+ const platform = browsers.detectBrowserPlatform();
629
+ if (!platform) {
630
+ throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
631
+ }
632
+ const stagingDir = join(CACHE_ROOT_DIR, `${STAGING_PREFIX}${randomUUID()}`);
633
+ const clearStaging = () => rmSync(stagingDir, { recursive: true, force: true });
634
+ const unzipLog = { lines: [] };
635
+ const runInstall = stagedInstaller(browsers, platform, stagingDir, options, unzipLog);
636
+ try {
637
+ const staged = await retryOnStall(
638
+ () => installWithCorruptArchiveRecovery(
639
+ runInstall,
640
+ clearStaging,
641
+ (err) => console.warn(
642
+ `[hyperframes] Downloaded browser archive was corrupt (${normalizeErrorMessage(err)}); re-downloading.`
643
+ )
644
+ ),
645
+ clearStaging
646
+ );
647
+ assertExecutableUnpacked(stagingDir, staged.executablePath);
648
+ unzipLog.lines = [];
649
+ return { executablePath: moveStagedInstallIntoCache(stagingDir, staged), source: "download" };
650
+ } catch (err) {
651
+ throw wrapDownloadFailureWithBrowserPathHint(err, unzipLog.lines);
652
+ } finally {
653
+ clearStaging();
654
+ }
655
+ }
656
+ function executableState(path) {
657
+ const stat = statSync(path, { throwIfNoEntry: false });
658
+ if (!stat) return "is missing";
659
+ if (!stat.isFile()) return "is not a file";
660
+ return stat.size > 0 ? "usable" : "is empty";
661
+ }
662
+ function isUsableExecutable(path) {
663
+ try {
664
+ return executableState(path) === "usable";
665
+ } catch {
666
+ return false;
667
+ }
668
+ }
669
+ function assertExecutableUnpacked(stagingDir, executablePath) {
670
+ const state = executableState(executablePath);
671
+ if (state === "usable") return;
672
+ throw new Error(
673
+ `the archive downloaded, but ${relative(stagingDir, executablePath)} ${state} after unzipping.`
674
+ );
675
+ }
676
+ function moveStagedInstallIntoCache(stagingDir, staged) {
677
+ const target = join(CACHE_DIR, relative(stagingDir, staged.path));
678
+ const aside = join(CACHE_ROOT_DIR, `${REPLACED_PREFIX}${randomUUID()}`);
679
+ mkdirSync(dirname2(target), { recursive: true });
680
+ let replaced = false;
681
+ try {
682
+ renameSync(target, aside);
683
+ replaced = true;
684
+ } catch (err) {
685
+ if (!isErrno(err, "ENOENT")) throw err;
686
+ }
687
+ try {
688
+ renameSync(staged.path, target);
689
+ } catch (err) {
690
+ if (replaced) renameSync(aside, target);
691
+ throw err;
692
+ }
693
+ if (replaced) rmSync(aside, { recursive: true, force: true });
694
+ return join(target, relative(staged.path, staged.executablePath));
695
+ }
696
+ var STAGING_PREFIX = ".chrome-staging-";
697
+ var REPLACED_PREFIX = ".chrome-replaced-";
698
+ var isInstallLeftover = (name) => name.startsWith(STAGING_PREFIX) || name.startsWith(REPLACED_PREFIX);
699
+ function removeInstallLeftovers() {
700
+ let names;
701
+ try {
702
+ names = readdirSync(CACHE_ROOT_DIR);
703
+ } catch (err) {
704
+ if (isErrno(err, "ENOENT")) return false;
705
+ throw err;
706
+ }
707
+ const leftovers = names.filter(isInstallLeftover);
708
+ for (const name of leftovers)
709
+ rmSync(join(CACHE_ROOT_DIR, name), { recursive: true, force: true });
710
+ return leftovers.length > 0;
711
+ }
712
+ async function sweepKilledInstalls() {
713
+ const names = existsSync(CACHE_ROOT_DIR) ? readdirSync(CACHE_ROOT_DIR) : [];
714
+ if (!names.some(isInstallLeftover)) return;
715
+ await withInstallLock(async () => removeInstallLeftovers());
716
+ }
717
+ function clearBrowser() {
718
+ const removedLeftovers = removeInstallLeftovers();
719
+ if (!existsSync(CACHE_DIR)) return removedLeftovers;
720
+ rmSync(CACHE_DIR, { recursive: true, force: true });
721
+ return true;
722
+ }
723
+ function isLinuxArm() {
724
+ return process.platform === "linux" && process.arch === "arm64";
725
+ }
726
+
727
+ export {
728
+ installProgressLine,
729
+ installLogLine,
730
+ CACHE_DIR,
731
+ withInstallLock,
732
+ releaseOwnedBrowserInstallLock,
733
+ _resetSystemFallbackWarnForTests,
734
+ findSystemBrowser,
735
+ findBrowser,
736
+ ensureBrowser,
737
+ isCorruptArchiveError,
738
+ installWithCorruptArchiveRecovery,
739
+ sweepKilledInstalls,
740
+ clearBrowser,
741
+ isLinuxArm
742
+ };