@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,1176 @@
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
+ gateRegistryItemsCompatibility
9
+ } from "./chunk-GPYVT5EE.js";
10
+ import {
11
+ initialModelForLanguage
12
+ } from "./chunk-HTUHQKDB.js";
13
+ import "./chunk-HFQ4CWHA.js";
14
+ import {
15
+ DEFAULT_MODEL,
16
+ hasFFmpeg
17
+ } from "./chunk-HPDTCOKE.js";
18
+ import "./chunk-WQ6ZXHFQ.js";
19
+ import {
20
+ findFFmpeg,
21
+ findFFprobe,
22
+ getFFmpegInstallHint
23
+ } from "./chunk-UMD3V7CU.js";
24
+ import {
25
+ Ee,
26
+ R,
27
+ Re,
28
+ Se,
29
+ ft,
30
+ ge,
31
+ me,
32
+ q,
33
+ ue
34
+ } from "./chunk-WMQNIQDJ.js";
35
+ import "./chunk-XT7X6QCP.js";
36
+ import {
37
+ writeNewFileSync
38
+ } from "./chunk-4YYJOFKS.js";
39
+ import {
40
+ listRegistryItems,
41
+ loadAllItems,
42
+ resolveItemWithDependencies
43
+ } from "./chunk-XX7LTW5Y.js";
44
+ import "./chunk-JHOCK3DG.js";
45
+ import {
46
+ installItem
47
+ } from "./chunk-XPTOJZJF.js";
48
+ import "./chunk-RGLQURIX.js";
49
+ import "./chunk-P6LJ4Y32.js";
50
+ import "./chunk-GMECXFAN.js";
51
+ import {
52
+ trackInitTemplate
53
+ } from "./chunk-GNEFDLFB.js";
54
+ import "./chunk-2UZQHDM7.js";
55
+ import "./chunk-NYEXNSHM.js";
56
+ import {
57
+ defineCommand,
58
+ runCommand
59
+ } from "./chunk-S3S4TGEH.js";
60
+ import "./chunk-54HJ63Q2.js";
61
+ import "./chunk-ISN5GRYI.js";
62
+ import {
63
+ c,
64
+ isColorSupported
65
+ } from "./chunk-VORQIH64.js";
66
+ import {
67
+ failCommand,
68
+ finishCommand
69
+ } from "./chunk-JVBRJMOP.js";
70
+ import "./chunk-TIQB63MX.js";
71
+ import "./chunk-IZCW2NKT.js";
72
+ import "./chunk-RNV3DM4S.js";
73
+ import "./chunk-DLA44CMS.js";
74
+ import "./chunk-UJZREAV6.js";
75
+ import "./chunk-VC76R6W2.js";
76
+ import "./chunk-X7HBSTCZ.js";
77
+ import {
78
+ CANVAS_DIMENSIONS,
79
+ HTML_BODY_CSS_HEIGHT_FIRST_RE,
80
+ HTML_BODY_CSS_WIDTH_FIRST_RE,
81
+ VIEWPORT_META_SIZE_RE,
82
+ normalizeResolutionFlag
83
+ } from "./chunk-B7RJV74O.js";
84
+ import "./chunk-DPVXBVLL.js";
85
+ import "./chunk-OFQWTKPW.js";
86
+ import "./chunk-634HSJ3J.js";
87
+ import "./chunk-FXMKHHPO.js";
88
+ import "./chunk-RQVDTPGD.js";
89
+ import "./chunk-AHX34EFP.js";
90
+ import "./chunk-LTGTN2TH.js";
91
+ import "./chunk-BL4U6U52.js";
92
+ import "./chunk-T2EUWCJE.js";
93
+ import "./chunk-T6AGUTZJ.js";
94
+ import "./chunk-XT6MXC7A.js";
95
+ import "./chunk-K4MJX7SR.js";
96
+ import "./chunk-4UMPIPCQ.js";
97
+ import "./chunk-4P7NX5BM.js";
98
+ import "./chunk-VAS6HQX3.js";
99
+ import "./chunk-6BNTGNGD.js";
100
+ import "./chunk-CZGHFATT.js";
101
+ import "./chunk-PKZ7RK5N.js";
102
+ import "./chunk-W2LGJSEN.js";
103
+ import "./chunk-MMQ52NIZ.js";
104
+ import "./chunk-BSQ7XANM.js";
105
+ import "./chunk-SDYDNHEE.js";
106
+ import "./chunk-RXATE6FZ.js";
107
+ import "./chunk-3422KMTD.js";
108
+ import "./chunk-UOFAE5RF.js";
109
+ import {
110
+ TRANSCRIPT_FILE
111
+ } from "./chunk-IR35BCLK.js";
112
+ import "./chunk-HU2SPFNG.js";
113
+ import "./chunk-KGPLIH7B.js";
114
+ import "./chunk-3GXQPCJC.js";
115
+ import "./chunk-M2WBOQ2Q.js";
116
+
117
+ // src/commands/initMedia.ts
118
+ var VIDEO_SRC = "__VIDEO_SRC__";
119
+ var AUDIO_SRC = "__AUDIO_SRC__";
120
+ var DURATION = "__VIDEO_DURATION__";
121
+ function toSrcValue(filename) {
122
+ return encodeURI(filename).replace(/#/g, "%23").replace(/\?/g, "%3F");
123
+ }
124
+ function openTag(tag, placeholder) {
125
+ return `<${tag}\\b[^>]*src="${placeholder}"[^>]*>`;
126
+ }
127
+ function stripPlaceholder(html, tag, placeholder) {
128
+ const open = openTag(tag, placeholder);
129
+ return html.replace(new RegExp(`${open}[\\s\\S]*?</${tag}>`, "g"), "").replace(new RegExp(open, "g"), "");
130
+ }
131
+ function setVideoAudio(html, hasAudio) {
132
+ return html.replace(new RegExp(openTag("video", VIDEO_SRC), "g"), (tag) => {
133
+ const cleaned = tag.replace(
134
+ /\s+([^\s=>"']+)(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>"']+))?/g,
135
+ (attr2, name) => name === "muted" || name === "data-has-audio" ? "" : attr2
136
+ );
137
+ const attr = hasAudio ? ' data-has-audio="true"' : " muted";
138
+ return cleaned.replace(/\s*>$/, `${attr}>`);
139
+ });
140
+ }
141
+ function patchMediaPlaceholders(html, opts) {
142
+ const legacyAudioSlot = new RegExp(openTag("audio", VIDEO_SRC)).test(html);
143
+ let out = html;
144
+ if (opts.video) {
145
+ out = stripPlaceholder(out, "audio", AUDIO_SRC);
146
+ if (legacyAudioSlot) {
147
+ if (!opts.video.hasAudio) out = stripPlaceholder(out, "audio", VIDEO_SRC);
148
+ } else {
149
+ out = setVideoAudio(out, opts.video.hasAudio);
150
+ }
151
+ const videoSrc = toSrcValue(opts.video.filename);
152
+ out = out.replaceAll(VIDEO_SRC, () => videoSrc);
153
+ } else if (opts.audio) {
154
+ out = stripPlaceholder(out, "video", VIDEO_SRC);
155
+ const audioSrc = toSrcValue(opts.audio.filename);
156
+ out = out.replaceAll(AUDIO_SRC, () => audioSrc);
157
+ out = out.replaceAll(VIDEO_SRC, () => audioSrc);
158
+ } else {
159
+ out = stripPlaceholder(out, "video", VIDEO_SRC);
160
+ out = stripPlaceholder(out, "audio", VIDEO_SRC);
161
+ out = stripPlaceholder(out, "audio", AUDIO_SRC);
162
+ }
163
+ const duration = opts.durationSeconds ? String(Math.round(opts.durationSeconds * 100) / 100) : "10";
164
+ return out.replaceAll(DURATION, duration);
165
+ }
166
+
167
+ // src/commands/init.ts
168
+ import {
169
+ existsSync as existsSync2,
170
+ mkdirSync,
171
+ copyFileSync,
172
+ writeFileSync,
173
+ readFileSync,
174
+ readdirSync
175
+ } from "fs";
176
+
177
+ // src/utils/copyDir.ts
178
+ import { cpSync } from "fs";
179
+ function copyDirSync(src, dest, options = {}) {
180
+ cpSync(src, dest, { ...options, recursive: true, filter: () => true });
181
+ }
182
+
183
+ // src/commands/init.ts
184
+ import { resolve, basename, join as join2, dirname } from "path";
185
+ import { fileURLToPath } from "url";
186
+ import { execFileSync, spawn } from "child_process";
187
+
188
+ // src/ui/banner.ts
189
+ var GRADIENT = [
190
+ [255, 255, 255],
191
+ // white
192
+ [116, 225, 185],
193
+ // #74E1B9 teal
194
+ [106, 220, 255]
195
+ // #6ADCFF cyan
196
+ ];
197
+ function lerp(a, b, t) {
198
+ return Math.round(a + (b - a) * t);
199
+ }
200
+ function gradientColor(t) {
201
+ const segments = GRADIENT.length - 1;
202
+ const scaled = t * segments;
203
+ const i = Math.min(Math.floor(scaled), segments - 1);
204
+ const frac = scaled - i;
205
+ const a = GRADIENT[i];
206
+ const b = GRADIENT[i + 1];
207
+ return [lerp(a[0], b[0], frac), lerp(a[1], b[1], frac), lerp(a[2], b[2], frac)];
208
+ }
209
+ function rgb(r, g, b, text) {
210
+ return `\x1B[38;2;${r};${g};${b}m${text}\x1B[0m`;
211
+ }
212
+ var BANNER = [
213
+ "\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
214
+ "\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D",
215
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
216
+ "\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u255A\u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551",
217
+ "\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551",
218
+ "\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
219
+ ];
220
+ function printBanner() {
221
+ if (!isColorSupported || !process.stdout.isTTY) return;
222
+ const maxWidth = Math.max(...BANNER.map((r) => r.length));
223
+ console.log();
224
+ for (const row of BANNER) {
225
+ let line = " ";
226
+ for (let col = 0; col < row.length; col++) {
227
+ const ch = row[col];
228
+ if (!ch || ch === " ") {
229
+ line += " ";
230
+ continue;
231
+ }
232
+ const t = maxWidth > 1 ? col / (maxWidth - 1) : 0;
233
+ const [r, g, b] = gradientColor(t);
234
+ line += rgb(r, g, b, ch);
235
+ }
236
+ console.log(line);
237
+ }
238
+ console.log();
239
+ }
240
+
241
+ // src/templates/generators.ts
242
+ var BUNDLED_TEMPLATES = [
243
+ {
244
+ id: "blank",
245
+ label: "Blank",
246
+ hint: "Centered Inter stage, paused timeline",
247
+ source: "bundled"
248
+ }
249
+ ];
250
+ async function resolveTemplateList() {
251
+ const bundled = [...BUNDLED_TEMPLATES];
252
+ const bundledIds = new Set(bundled.map((t) => t.id));
253
+ const entries = await listRegistryItems({ type: "hyperframes:example" });
254
+ const items = await loadAllItems(entries);
255
+ const remoteOptions = items.filter((item) => !bundledIds.has(item.name)).map((item) => ({
256
+ id: item.name,
257
+ label: item.title,
258
+ hint: item.description,
259
+ source: "remote"
260
+ }));
261
+ return [...bundled, ...remoteOptions];
262
+ }
263
+
264
+ // src/templates/remote.ts
265
+ import { existsSync } from "fs";
266
+ import { join } from "path";
267
+ async function fetchRemoteTemplate(templateId, destDir) {
268
+ const items = await resolveItemWithDependencies(templateId);
269
+ const warnings = gateRegistryItemsCompatibility(items);
270
+ for (const warning of warnings) {
271
+ process.stderr.write(`hyperframes:registry ${warning}
272
+ `);
273
+ }
274
+ for (const item of items) {
275
+ await installItem(item, { destDir });
276
+ }
277
+ if (!existsSync(join(destDir, "index.html"))) {
278
+ throw new Error(
279
+ `Example "${templateId}" installed but missing index.html. The registry item may be malformed.`
280
+ );
281
+ }
282
+ }
283
+
284
+ // src/commands/init.ts
285
+ var examples = [
286
+ ["Create a project with the interactive wizard", "framey init my-video"],
287
+ ["Pick a starter example", "framey init my-video --example warm-grain"],
288
+ ["Scaffold a 4K project", "framey init my-video --resolution 4k"],
289
+ ["Scaffold a portrait video", "framey init my-video --resolution portrait"],
290
+ ["Start from an existing video file", "framey init my-video --video clip.mp4"],
291
+ ["Start from an audio file", "framey init my-video --audio track.mp3"],
292
+ ["Scaffold with Tailwind CSS", "framey init my-video --tailwind"],
293
+ ["Non-interactive mode (for CI or AI agents)", "framey init my-video --non-interactive"],
294
+ [
295
+ "Opt out of the GitHub skills check (CI/tests only)",
296
+ "HYPERFRAMES_SKIP_SKILLS=1 hyperframes init my-video --non-interactive"
297
+ ]
298
+ ];
299
+ function resolveScaffoldTemplateId(exampleFlag, hasMediaFile) {
300
+ const example = exampleFlag === "agent" ? "blank" : exampleFlag;
301
+ if (example && example !== "blank") return example;
302
+ if (hasMediaFile) return "from-file";
303
+ return "blank";
304
+ }
305
+ var WEB_CODECS = /* @__PURE__ */ new Set(["h264", "vp8", "vp9", "av1"]);
306
+ var DEFAULT_META = {
307
+ durationSeconds: 5,
308
+ width: 1920,
309
+ height: 1080,
310
+ fps: 30,
311
+ // ffprobe unavailable: assume sound. A wrong guess fails loudly at RENDER (lint catches it only once #3638 lands); assuming silence would mute real audio.
312
+ hasAudio: true,
313
+ videoCodec: "h264"
314
+ };
315
+ var TAILWIND_BROWSER_VERSION = "4.2.4";
316
+ var TAILWIND_BROWSER_SRC = `https://cdn.jsdelivr.net/npm/@tailwindcss/browser@${TAILWIND_BROWSER_VERSION}/dist/index.global.js`;
317
+ var TAILWIND_BROWSER_INTEGRITY = "sha384-v5YF9xS+gLRWdvrQ0u/WRbCkjSIH0NjHIPe8tBL1ZRrmI7PiSH6LLdzs0aAIMCuh";
318
+ function resolveVideoDurationSeconds({
319
+ streamDuration,
320
+ frameDuration,
321
+ formatDuration
322
+ }) {
323
+ return [streamDuration, frameDuration, formatDuration].find(
324
+ (duration) => Number.isFinite(duration) && duration > 0
325
+ ) ?? DEFAULT_META.durationSeconds;
326
+ }
327
+ function probeVideo(filePath) {
328
+ try {
329
+ const ffprobePath = findFFprobe();
330
+ if (!ffprobePath) return void 0;
331
+ const raw = execFileSync(
332
+ ffprobePath,
333
+ ["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", "--", filePath],
334
+ { encoding: "utf-8", timeout: 15e3 }
335
+ );
336
+ const parsed = JSON.parse(raw);
337
+ const streams = parsed.streams ?? [];
338
+ const videoStream = streams.find((s) => s.codec_type === "video");
339
+ if (!videoStream) return void 0;
340
+ const hasAudio = streams.some((s) => s.codec_type === "audio");
341
+ let fps = 30;
342
+ const fpsStr = videoStream.avg_frame_rate ?? videoStream.r_frame_rate;
343
+ if (fpsStr) {
344
+ const parts = fpsStr.split("/");
345
+ const num = parseFloat(parts[0] ?? "");
346
+ const den = parseFloat(parts[1] ?? "1");
347
+ if (den !== 0 && !Number.isNaN(num) && !Number.isNaN(den)) {
348
+ fps = Math.round(num / den * 100) / 100;
349
+ }
350
+ }
351
+ const streamDuration = parseFloat(videoStream.duration ?? "");
352
+ const frameCount = parseInt(videoStream.nb_frames ?? "", 10);
353
+ const frameDuration = Number.isFinite(frameCount) && fps > 0 ? frameCount / fps : NaN;
354
+ const formatDuration = parseFloat(parsed.format?.duration ?? "");
355
+ const durationSeconds = resolveVideoDurationSeconds({
356
+ streamDuration,
357
+ frameDuration,
358
+ formatDuration
359
+ });
360
+ const [sarW, sarH] = (videoStream.sample_aspect_ratio ?? "").split(":").map(Number);
361
+ const sar = sarW && sarH ? sarW / sarH : 1;
362
+ const width = Math.round((videoStream.width ?? 1920) * sar);
363
+ const height = videoStream.height ?? 1080;
364
+ const turn = Number(
365
+ videoStream.side_data_list?.find((d) => d.rotation !== void 0)?.rotation ?? videoStream.tags?.rotate ?? 0
366
+ );
367
+ const turned = Math.abs(turn) % 180 === 90;
368
+ return {
369
+ durationSeconds,
370
+ width: turned ? height : width,
371
+ height: turned ? width : height,
372
+ fps,
373
+ hasAudio,
374
+ videoCodec: videoStream.codec_name ?? "unknown"
375
+ };
376
+ } catch {
377
+ return void 0;
378
+ }
379
+ }
380
+ function clipFrame(templateId, clip) {
381
+ if (templateId !== "from-file" || !clip || !(clip.width > 0 && clip.height > 0)) return void 0;
382
+ const even = (n) => 2 * Math.round(n / 2);
383
+ const frame = clip.width >= clip.height ? { width: even(1080 * clip.width / clip.height), height: 1080 } : { width: 1080, height: even(1080 * clip.height / clip.width) };
384
+ return frame.width === 1920 && frame.height === 1080 ? void 0 : frame;
385
+ }
386
+ function isWebCompatible(codec) {
387
+ return WEB_CODECS.has(codec.toLowerCase());
388
+ }
389
+ function transcodeToMp4(inputPath, outputPath) {
390
+ return new Promise((resolvePromise) => {
391
+ const ffmpegPath = findFFmpeg();
392
+ if (!ffmpegPath) {
393
+ resolvePromise(false);
394
+ return;
395
+ }
396
+ const child = spawn(
397
+ ffmpegPath,
398
+ [
399
+ "-i",
400
+ inputPath,
401
+ "-c:v",
402
+ "libx264",
403
+ "-preset",
404
+ "fast",
405
+ "-crf",
406
+ "18",
407
+ "-c:a",
408
+ "aac",
409
+ "-b:a",
410
+ "192k",
411
+ "-y",
412
+ outputPath
413
+ ],
414
+ { stdio: "ignore", windowsHide: true }
415
+ );
416
+ child.on("close", (code) => resolvePromise(code === 0));
417
+ child.on("error", () => resolvePromise(false));
418
+ });
419
+ }
420
+ function resolveAssetDir(devSegments, builtSegments) {
421
+ const base = dirname(fileURLToPath(import.meta.url));
422
+ const devPath = resolve(base, ...devSegments);
423
+ const builtPath = resolve(base, ...builtSegments);
424
+ return existsSync2(devPath) ? devPath : builtPath;
425
+ }
426
+ function getStaticTemplateDir(templateId) {
427
+ const base = dirname(fileURLToPath(import.meta.url));
428
+ const devPath = resolve(base, "..", "templates", templateId);
429
+ if (existsSync2(devPath)) return devPath;
430
+ const registryPath = resolve(base, "..", "..", "..", "..", "registry", "examples", templateId);
431
+ if (existsSync2(registryPath)) return registryPath;
432
+ return resolve(base, "templates", templateId);
433
+ }
434
+ function getSharedTemplateDir() {
435
+ return resolveAssetDir(["..", "templates", "_shared"], ["templates", "_shared"]);
436
+ }
437
+ var MAX_FOLDER_NAME = 255;
438
+ function nameTooLongMessage(name, platform = process.platform) {
439
+ const inBytes = platform === "linux";
440
+ const unit = inBytes ? "bytes" : "characters";
441
+ for (const folder of name.split(platform === "win32" ? /[\\/]/ : "/")) {
442
+ const length = inBytes ? Buffer.byteLength(folder) : folder.length;
443
+ if (length > MAX_FOLDER_NAME)
444
+ return `That name is ${length} ${unit} long; a folder name can be at most ${MAX_FOLDER_NAME} ${unit}.`;
445
+ }
446
+ return null;
447
+ }
448
+ function toPackageName(projectName) {
449
+ const normalized = basename(projectName).trim().toLowerCase().replace(/^[._]+/, "").replace(/[^a-z0-9._~-]+/g, "-").replace(/-+/g, "-").replace(/^[-.]+|[-.]+$/g, "");
450
+ return normalized || "framey-project";
451
+ }
452
+ function frameyScript(command) {
453
+ return `framey ${command}`;
454
+ }
455
+ function buildPackageScripts() {
456
+ return {
457
+ dev: frameyScript("preview"),
458
+ check: frameyScript("check"),
459
+ render: frameyScript("render")
460
+ };
461
+ }
462
+ function writeDefaultPackageJson(destDir, projectName) {
463
+ const packageJsonPath = resolve(destDir, "package.json");
464
+ if (existsSync2(packageJsonPath)) return;
465
+ writeNewFileSync(
466
+ packageJsonPath,
467
+ `${JSON.stringify(
468
+ {
469
+ name: toPackageName(projectName),
470
+ private: true,
471
+ type: "module",
472
+ scripts: buildPackageScripts()
473
+ },
474
+ null,
475
+ 2
476
+ )}
477
+ `
478
+ );
479
+ }
480
+ function listHtmlFiles(dir) {
481
+ const files = [];
482
+ const ignoredDirs = /* @__PURE__ */ new Set([".git", "dist", "node_modules"]);
483
+ function walk(currentDir) {
484
+ for (const entry of readdirSync(currentDir, { withFileTypes: true })) {
485
+ const entryPath = join2(currentDir, entry.name);
486
+ if (entry.isDirectory()) {
487
+ if (!ignoredDirs.has(entry.name)) walk(entryPath);
488
+ continue;
489
+ }
490
+ if (entry.isFile() && entry.name.endsWith(".html")) {
491
+ files.push(entryPath);
492
+ }
493
+ }
494
+ }
495
+ walk(dir);
496
+ return files;
497
+ }
498
+ function injectTailwindBrowserScript(html) {
499
+ if (html.includes(TAILWIND_BROWSER_SRC)) return html;
500
+ const script = [
501
+ `<script>`,
502
+ `window.__tailwindReady=new Promise(function(resolve){`,
503
+ `var loaded=document.readyState==="complete";`,
504
+ `var resolved=false;`,
505
+ `var observer;`,
506
+ `function readTailwindCss(){var styles=document.querySelectorAll("style");for(var i=styles.length-1;i>=0;i--){var text=styles[i].textContent||"";if(text.indexOf("tailwindcss v")!==-1)return text;}return "";}`,
507
+ `function finish(){if(resolved||!loaded||!readTailwindCss())return;resolved=true;if(observer)observer.disconnect();resolve(true);}`,
508
+ `observer=new MutationObserver(finish);`,
509
+ `observer.observe(document.documentElement,{childList:true,subtree:true,characterData:true});`,
510
+ `if(loaded){finish();}else{window.addEventListener("load",function(){loaded=true;finish();},{once:true});}`,
511
+ `});`,
512
+ `</script>`,
513
+ `<script src="${TAILWIND_BROWSER_SRC}" integrity="${TAILWIND_BROWSER_INTEGRITY}" crossorigin="anonymous"></script>`
514
+ ].join("\n");
515
+ if (/<\/head>/i.test(html)) {
516
+ return html.replace(/<\/head>/i, (closingHead) => `
517
+ ${script}
518
+ ${closingHead}`);
519
+ }
520
+ return `${script}
521
+ ${html}`;
522
+ }
523
+ function writeTailwindSupport(destDir) {
524
+ for (const file of listHtmlFiles(destDir)) {
525
+ const html = readFileSync(file, "utf-8");
526
+ writeFileSync(file, injectTailwindBrowserScript(html), "utf-8");
527
+ }
528
+ }
529
+ function patchVideoSrc(dir, media) {
530
+ const htmlFiles = readdirSync(dir, { withFileTypes: true, recursive: true }).filter((e) => e.isFile() && e.name.endsWith(".html")).map((e) => join2(e.parentPath, e.name));
531
+ for (const file of htmlFiles) {
532
+ writeFileSync(file, patchMediaPlaceholders(readFileSync(file, "utf-8"), media), "utf-8");
533
+ }
534
+ }
535
+ async function finishScaffold(destDir, templateId, tailwind) {
536
+ trackInitTemplate(templateId, { tailwind });
537
+ const transcriptFile = resolve(destDir, TRANSCRIPT_FILE);
538
+ if (existsSync2(transcriptFile)) await patchTranscript(destDir, transcriptFile);
539
+ }
540
+ async function patchTranscript(dir, transcriptPath) {
541
+ const { loadTranscript, patchCaptionHtml } = await import("./normalize-FASIPBUM.js");
542
+ const { words } = loadTranscript(transcriptPath);
543
+ if (words.length === 0) return;
544
+ patchCaptionHtml(dir, words);
545
+ }
546
+ async function handleVideoFile(videoPath, destDir, interactive, keepOriginal) {
547
+ const probed = probeVideo(videoPath);
548
+ let meta = { ...DEFAULT_META };
549
+ let localVideoName = basename(videoPath);
550
+ if (probed) {
551
+ meta = probed;
552
+ if (interactive) {
553
+ R.info(
554
+ `Video: ${meta.width}x${meta.height}, ${meta.durationSeconds.toFixed(1)}s, ${meta.fps}fps${meta.hasAudio ? ", has audio" : ""}`
555
+ );
556
+ }
557
+ } else {
558
+ const msg = `ffprobe not found \u2014 using defaults (1920x1080, 5s, 30fps) and assuming the video has sound (data-has-audio="true"); if it is silent, replace that with muted. Install: ${getFFmpegInstallHint()}`;
559
+ if (interactive) {
560
+ R.warn(msg);
561
+ } else {
562
+ console.log(c.warn(msg));
563
+ }
564
+ }
565
+ if (probed && !keepOriginal && !isWebCompatible(probed.videoCodec)) {
566
+ if (interactive) {
567
+ R.warn(
568
+ c.warn(`Video codec "${probed.videoCodec}" is not supported by web browsers.`)
569
+ );
570
+ } else {
571
+ console.log(c.warn(`Video codec "${probed.videoCodec}" is not supported by browsers.`));
572
+ }
573
+ if (hasFFmpeg()) {
574
+ let shouldTranscode = !interactive;
575
+ if (interactive) {
576
+ const transcode = await Ee({
577
+ message: "Transcode to H.264 MP4 for browser playback?",
578
+ options: [
579
+ {
580
+ value: "yes",
581
+ label: "Yes, transcode",
582
+ hint: "converts to H.264 MP4"
583
+ },
584
+ {
585
+ value: "no",
586
+ label: "No, keep original",
587
+ hint: "video won't play in browser"
588
+ }
589
+ ]
590
+ });
591
+ if (q(transcode)) {
592
+ me("Setup cancelled.");
593
+ finishCommand(0);
594
+ }
595
+ shouldTranscode = transcode === "yes";
596
+ }
597
+ if (shouldTranscode) {
598
+ const mp4Name = localVideoName.replace(/\.[^.]+$/, ".mp4");
599
+ const mp4Path = resolve(destDir, mp4Name);
600
+ const spin = ft();
601
+ spin.start("Transcoding to H.264 MP4...");
602
+ const ok = await transcodeToMp4(videoPath, mp4Path);
603
+ if (ok) {
604
+ spin.stop(c.success(`Transcoded to ${mp4Name}`));
605
+ localVideoName = mp4Name;
606
+ } else {
607
+ spin.stop(c.warn("Transcode failed \u2014 copying original file"));
608
+ copyFileSync(videoPath, resolve(destDir, localVideoName));
609
+ }
610
+ } else {
611
+ copyFileSync(videoPath, resolve(destDir, localVideoName));
612
+ }
613
+ } else {
614
+ if (interactive) {
615
+ R.warn(c.dim("ffmpeg not installed \u2014 cannot transcode."));
616
+ R.info(c.accent(`Install: ${getFFmpegInstallHint()}`));
617
+ } else {
618
+ console.log(c.warn("ffmpeg not installed \u2014 cannot transcode. Copying original."));
619
+ console.log(c.dim("Install: ") + c.accent(getFFmpegInstallHint()));
620
+ }
621
+ copyFileSync(videoPath, resolve(destDir, localVideoName));
622
+ }
623
+ } else {
624
+ copyFileSync(videoPath, resolve(destDir, localVideoName));
625
+ }
626
+ return { meta, localVideoName };
627
+ }
628
+ function applyResolutionPreset(destDir, resolution) {
629
+ applyCanvasSize(destDir, CANVAS_DIMENSIONS[resolution], resolution);
630
+ }
631
+ function applyCanvasSize(destDir, { width, height }, resolution) {
632
+ for (const file of listHtmlFiles(destDir)) {
633
+ let html = readFileSync(file, "utf-8");
634
+ let changed = false;
635
+ const dataWidthRe = /(data-width=)["'](\d+)["']/g;
636
+ if (dataWidthRe.test(html)) {
637
+ html = html.replace(dataWidthRe, `$1"${width}"`);
638
+ changed = true;
639
+ }
640
+ const dataHeightRe = /(data-height=)["'](\d+)["']/g;
641
+ if (dataHeightRe.test(html)) {
642
+ html = html.replace(dataHeightRe, `$1"${height}"`);
643
+ changed = true;
644
+ }
645
+ const htmlOpenRe = /<html\b([^>]*)>/i;
646
+ const htmlOpen = html.match(htmlOpenRe);
647
+ if (htmlOpen && resolution) {
648
+ const attrs = htmlOpen[1] ?? "";
649
+ let next;
650
+ if (/data-resolution=/.test(attrs)) {
651
+ next = attrs.replace(/data-resolution=["'][^"']*["']/, `data-resolution="${resolution}"`);
652
+ } else {
653
+ next = `${attrs.replace(/\s+$/, "")} data-resolution="${resolution}"`;
654
+ }
655
+ if (next !== attrs) {
656
+ html = html.replace(htmlOpenRe, `<html${next}>`);
657
+ changed = true;
658
+ }
659
+ }
660
+ if (HTML_BODY_CSS_WIDTH_FIRST_RE.test(html)) {
661
+ html = html.replace(HTML_BODY_CSS_WIDTH_FIRST_RE, `$1${width}px$3${height}px`);
662
+ changed = true;
663
+ }
664
+ if (HTML_BODY_CSS_HEIGHT_FIRST_RE.test(html)) {
665
+ html = html.replace(HTML_BODY_CSS_HEIGHT_FIRST_RE, `$1${height}px$3${width}px`);
666
+ changed = true;
667
+ }
668
+ if (VIEWPORT_META_SIZE_RE.test(html)) {
669
+ html = html.replace(VIEWPORT_META_SIZE_RE, `$1${width}$3${height}`);
670
+ changed = true;
671
+ }
672
+ if (changed) writeFileSync(file, html, "utf-8");
673
+ }
674
+ }
675
+ async function scaffoldProject(destDir, name, templateId, media, tailwind = false, canvas, authoringSkill) {
676
+ mkdirSync(destDir, { recursive: true });
677
+ const templateDir = getStaticTemplateDir(templateId);
678
+ if (existsSync2(join2(templateDir, "index.html"))) {
679
+ copyDirSync(templateDir, destDir);
680
+ } else {
681
+ await fetchRemoteTemplate(templateId, destDir);
682
+ }
683
+ patchVideoSrc(destDir, media);
684
+ if (tailwind) writeTailwindSupport(destDir);
685
+ if (typeof canvas === "string") applyResolutionPreset(destDir, canvas);
686
+ else if (canvas) applyCanvasSize(destDir, canvas);
687
+ writeFileSync(
688
+ resolve(destDir, "meta.json"),
689
+ JSON.stringify(
690
+ {
691
+ id: name,
692
+ name,
693
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
694
+ },
695
+ null,
696
+ 2
697
+ ),
698
+ "utf-8"
699
+ );
700
+ if (!existsSync2(resolve(destDir, "hyperframes.json"))) {
701
+ const { createProjectConfig, DEFAULT_PROJECT_CONFIG } = await import("./projectConfig-3MZAYVTS.js");
702
+ const { normalizeSkillSlug } = await import("./skill-ZHVLH7KX.js");
703
+ const skill = normalizeSkillSlug(authoringSkill);
704
+ createProjectConfig(
705
+ destDir,
706
+ skill ? { ...DEFAULT_PROJECT_CONFIG, authoringSkill: skill } : DEFAULT_PROJECT_CONFIG
707
+ );
708
+ }
709
+ writeDefaultPackageJson(destDir, name);
710
+ const sharedDir = getSharedTemplateDir();
711
+ if (existsSync2(sharedDir)) {
712
+ for (const entry of readdirSync(sharedDir, { withFileTypes: true })) {
713
+ const src = join2(sharedDir, entry.name);
714
+ const dest = resolve(destDir, entry.name);
715
+ if (entry.isFile() || entry.isSymbolicLink()) {
716
+ copyFileSync(src, dest);
717
+ }
718
+ }
719
+ }
720
+ }
721
+ async function keepSkillsCurrent(_destDir) {
722
+ console.log();
723
+ console.log(
724
+ c.dim(
725
+ "AI coding skills ship in the Framey repository (skills/); install them from that checkout."
726
+ )
727
+ );
728
+ }
729
+ var init_default = defineCommand({
730
+ meta: {
731
+ name: "init",
732
+ description: "Scaffold a new composition project"
733
+ },
734
+ args: {
735
+ name: { type: "positional", description: "Project name", required: false },
736
+ example: {
737
+ type: "string",
738
+ description: "Example name (e.g. warm-grain, swiss-grid, blank)",
739
+ alias: "e"
740
+ },
741
+ // Accepted-but-errored so users who still type the old flag get a clear
742
+ // message rather than citty silently ignoring it and producing a blank
743
+ // project. The actual behavior is gone — this exists purely for the
744
+ // diagnostic. `hidden` keeps it out of --help output so new users aren't
745
+ // taught about a flag that's already gone.
746
+ template: {
747
+ type: "string",
748
+ description: "[renamed] Use --example instead.",
749
+ alias: "t",
750
+ hidden: true
751
+ },
752
+ video: {
753
+ type: "string",
754
+ description: "Path to a video file (MP4, WebM, MOV)",
755
+ alias: "v"
756
+ },
757
+ "video-legacy": {
758
+ type: "string",
759
+ description: "[renamed] Use --video (or -v) instead of -V.",
760
+ alias: "V",
761
+ hidden: true
762
+ },
763
+ audio: {
764
+ type: "string",
765
+ description: "Path to an audio file (MP3, WAV, M4A)",
766
+ alias: "a"
767
+ },
768
+ "skip-transcribe": {
769
+ type: "boolean",
770
+ description: "Skip whisper transcription"
771
+ },
772
+ "keep-original": {
773
+ type: "boolean",
774
+ description: "Copy the --video file as is, without converting it to H.264 MP4"
775
+ },
776
+ model: {
777
+ type: "string",
778
+ description: "Whisper model for transcription (e.g. tiny.en, base.en, small.en, medium.en, large)"
779
+ },
780
+ language: {
781
+ type: "string",
782
+ description: "Language code for transcription (e.g. en, es, ja). Filters out non-target speech."
783
+ },
784
+ "non-interactive": {
785
+ type: "boolean",
786
+ description: "Disable interactive prompts (for CI/agents)"
787
+ },
788
+ agent: {
789
+ type: "boolean",
790
+ hidden: true,
791
+ description: "Deprecated alias; default init is the centered blank"
792
+ },
793
+ "skip-skills": {
794
+ type: "boolean",
795
+ description: "[temporarily ignored] init always checks AI skills against GitHub while the skills.sh registry catches up; set HYPERFRAMES_SKIP_SKILLS=1 to opt out (CI/tests)"
796
+ },
797
+ tailwind: {
798
+ type: "boolean",
799
+ description: "Add Tailwind CSS browser-runtime support"
800
+ },
801
+ resolution: {
802
+ type: "string",
803
+ description: "Canvas resolution preset: landscape (1920x1080), portrait (1080x1920), landscape-4k (3840x2160), portrait-4k (2160x3840), square (1080x1080), square-4k (2160x2160). Aliases: 1080p, 4k, uhd, 1080p-square, square-1080p, 4k-square. Default: a --video clip's own shape as it plays, 1080 on the short side (4:3 -> 1440x1080), else the template's dimensions (typically 1920x1080)."
804
+ },
805
+ skill: {
806
+ type: "string",
807
+ description: "Owning authoring skill slug (e.g. hyperframes). Stamped into hyperframes.json so every render of this project is attributed to it on anonymous telemetry, without re-passing --skill on each render. Ignored unless it is a slug."
808
+ }
809
+ },
810
+ async run({ args }) {
811
+ if (args.template !== void 0) {
812
+ console.error(
813
+ c.error(
814
+ `The --template flag was renamed to --example. Example:
815
+ framey init ${args.name ?? "my-video"} --example "${args.template}"`
816
+ )
817
+ );
818
+ failCommand();
819
+ }
820
+ if (args["video-legacy"] !== void 0) {
821
+ console.error(
822
+ c.error(
823
+ `The -V short flag no longer maps to --video. Use --video (or -v). Example:
824
+ framey init ${args.name ?? "my-video"} --video "${args["video-legacy"]}"`
825
+ )
826
+ );
827
+ failCommand();
828
+ }
829
+ const exampleFlag = args.example;
830
+ const videoFlag = args.video;
831
+ const audioFlag = args.audio;
832
+ const skipTranscribe = args["skip-transcribe"] === true;
833
+ const keepOriginal = args["keep-original"] === true;
834
+ const skipSkills = args["skip-skills"] === true || process.env.HYPERFRAMES_SKIP_SKILLS === "1";
835
+ const tailwind = args.tailwind === true;
836
+ const nonInteractive = args["non-interactive"] === true || args.agent === true;
837
+ const modelFlag = args.model;
838
+ const languageFlag = args.language;
839
+ const initialTranscriptionModel = initialModelForLanguage(
840
+ modelFlag ?? DEFAULT_MODEL,
841
+ languageFlag
842
+ );
843
+ const interactive = !nonInteractive && process.stdout.isTTY === true;
844
+ let resolutionPreset;
845
+ if (args.resolution !== void 0) {
846
+ resolutionPreset = normalizeResolutionFlag(args.resolution);
847
+ if (!resolutionPreset) {
848
+ console.error(
849
+ c.error(
850
+ `Invalid --resolution: "${args.resolution}". Use one of: landscape, portrait, landscape-4k, portrait-4k, square, square-4k (or aliases 1080p, 4k, uhd, 1080p-square, square-1080p, 4k-square).`
851
+ )
852
+ );
853
+ failCommand();
854
+ }
855
+ }
856
+ if (!interactive) {
857
+ const templateId2 = resolveScaffoldTemplateId(exampleFlag, Boolean(videoFlag || audioFlag));
858
+ const name2 = args.name ?? "my-video";
859
+ const destDir2 = resolve(name2);
860
+ const tooLong2 = nameTooLongMessage(destDir2);
861
+ if (tooLong2) {
862
+ console.error(c.error(tooLong2));
863
+ failCommand();
864
+ }
865
+ if (existsSync2(destDir2) && readdirSync(destDir2).length > 0) {
866
+ console.error(c.error(`Directory already exists and is not empty: ${name2}`));
867
+ failCommand();
868
+ }
869
+ if (videoFlag && audioFlag) {
870
+ console.error(c.error("Cannot use --video and --audio together"));
871
+ failCommand();
872
+ }
873
+ const videoPath = videoFlag ? resolve(videoFlag) : void 0;
874
+ if (videoPath && !existsSync2(videoPath)) {
875
+ console.error(c.error(`Video file not found: ${videoFlag}`));
876
+ failCommand();
877
+ }
878
+ const audioPath = audioFlag ? resolve(audioFlag) : void 0;
879
+ if (audioPath && !existsSync2(audioPath)) {
880
+ console.error(c.error(`Audio file not found: ${audioFlag}`));
881
+ failCommand();
882
+ }
883
+ mkdirSync(destDir2, { recursive: true });
884
+ let localVideoName2;
885
+ let videoHasAudio2 = true;
886
+ let videoDuration2;
887
+ let videoSize2;
888
+ let sourceFilePath2;
889
+ if (videoPath) {
890
+ sourceFilePath2 = videoPath;
891
+ const result = await handleVideoFile(videoPath, destDir2, false, keepOriginal);
892
+ localVideoName2 = result.localVideoName;
893
+ videoHasAudio2 = result.meta.hasAudio;
894
+ videoDuration2 = result.meta.durationSeconds;
895
+ videoSize2 = result.meta;
896
+ console.log(
897
+ `Video: ${result.meta.width}x${result.meta.height}, ${result.meta.durationSeconds.toFixed(1)}s`
898
+ );
899
+ }
900
+ if (audioPath) {
901
+ sourceFilePath2 = audioPath;
902
+ copyFileSync(audioPath, resolve(destDir2, basename(audioPath)));
903
+ const { getMediaDurationSeconds } = await import("./transcribe-UJESPBT5.js");
904
+ videoDuration2 = getMediaDurationSeconds(audioPath) ?? void 0;
905
+ console.log(`Audio: ${basename(audioPath)}`);
906
+ }
907
+ if (sourceFilePath2 && !skipTranscribe) {
908
+ try {
909
+ const { ensureWhisper, ensureModel } = await import("./manager-WA4F2GST.js");
910
+ await ensureWhisper();
911
+ await ensureModel(initialTranscriptionModel);
912
+ console.log("Transcribing...");
913
+ const { transcribe: runTranscribe } = await import("./transcribe-UJESPBT5.js");
914
+ const result = await runTranscribe(sourceFilePath2, destDir2, {
915
+ model: modelFlag,
916
+ language: languageFlag
917
+ });
918
+ console.log(
919
+ `Transcribed: ${result.wordCount} words (${result.durationSeconds.toFixed(1)}s)`
920
+ );
921
+ if (!videoDuration2) videoDuration2 = result.durationSeconds;
922
+ } catch (err) {
923
+ console.log(`Transcription skipped: ${err instanceof Error ? err.message : err}`);
924
+ }
925
+ }
926
+ try {
927
+ const media = {
928
+ video: localVideoName2 ? { filename: localVideoName2, hasAudio: videoHasAudio2 } : void 0,
929
+ audio: audioPath ? { filename: basename(audioPath) } : void 0,
930
+ durationSeconds: videoDuration2
931
+ };
932
+ await scaffoldProject(
933
+ destDir2,
934
+ basename(destDir2),
935
+ templateId2,
936
+ media,
937
+ tailwind,
938
+ resolutionPreset ?? clipFrame(templateId2, videoSize2),
939
+ args.skill
940
+ );
941
+ } catch (err) {
942
+ console.error(
943
+ c.error(
944
+ `Failed to scaffold example "${templateId2}": ${err instanceof Error ? err.message : err}`
945
+ )
946
+ );
947
+ console.error(c.dim("Use --example blank for offline use."));
948
+ failCommand();
949
+ }
950
+ await finishScaffold(destDir2, templateId2, tailwind);
951
+ console.log(c.success(`Created ${c.accent(name2 + "/")}`));
952
+ for (const f of readdirSync(destDir2).filter((f2) => !f2.startsWith("."))) {
953
+ console.log(` ${c.accent(f)}`);
954
+ }
955
+ if (!skipSkills) {
956
+ await keepSkillsCurrent(destDir2);
957
+ }
958
+ console.log();
959
+ console.log("Get started:");
960
+ console.log();
961
+ if (skipSkills) {
962
+ console.log(
963
+ ` ${c.accent("1.")} Use your Framey plugin, or install the skills from the Framey checkout (skills/).`
964
+ );
965
+ } else {
966
+ console.log(
967
+ ` ${c.accent("1.")} Restart your AI agent (new session) so it loads the skills.`
968
+ );
969
+ }
970
+ console.log();
971
+ console.log(` ${c.accent("2.")} Open this project with your AI coding agent:`);
972
+ console.log(
973
+ ` ${c.accent(`cd ${name2}`)} then start ${c.accent("Claude Code")}, ${c.accent("Cursor")}, or your preferred agent`
974
+ );
975
+ console.log();
976
+ console.log(` ${c.accent("3.")} Try a starter prompt:`);
977
+ console.log(` ${c.dim('"Using /framey, create a 15-second intro about [your topic]"')}`);
978
+ console.log(` ${c.dim("More patterns: hyperframes.heygen.com/prompting/overview")}`);
979
+ console.log();
980
+ console.log(` ${c.accent("4.")} Preview in the browser:`);
981
+ console.log(` ${c.accent(`cd ${name2}`)} && ${c.accent("npm run dev")}`);
982
+ console.log();
983
+ console.log(` ${c.accent("5.")} Check the composition:`);
984
+ console.log(` ${c.accent(`cd ${name2}`)} && ${c.accent("npm run check")}`);
985
+ console.log();
986
+ console.log(` ${c.accent("6.")} Render to MP4 when ready:`);
987
+ console.log(` ${c.accent(`cd ${name2}`)} && ${c.accent("npm run render")}`);
988
+ console.log();
989
+ console.log(` ${c.dim("Full docs: hyperframes.heygen.com")}`);
990
+ return;
991
+ }
992
+ printBanner();
993
+ ge("Create a new Framey project");
994
+ let name;
995
+ const hasPositionalName = args.name !== void 0 && args.name !== "";
996
+ if (hasPositionalName) {
997
+ name = args.name ?? "my-video";
998
+ } else {
999
+ const nameResult = await Re({
1000
+ message: "Project name",
1001
+ placeholder: "my-video",
1002
+ defaultValue: "my-video"
1003
+ });
1004
+ if (q(nameResult)) {
1005
+ me("Setup cancelled.");
1006
+ finishCommand(0);
1007
+ }
1008
+ name = nameResult;
1009
+ }
1010
+ const destDir = resolve(name);
1011
+ const tooLong = nameTooLongMessage(destDir);
1012
+ if (tooLong) {
1013
+ R.error(tooLong);
1014
+ me("Setup cancelled.");
1015
+ failCommand();
1016
+ }
1017
+ if (existsSync2(destDir) && readdirSync(destDir).length > 0) {
1018
+ const overwrite = await ue({
1019
+ message: `Directory ${c.accent(name)} already exists and is not empty. Overwrite?`,
1020
+ initialValue: false
1021
+ });
1022
+ if (q(overwrite) || !overwrite) {
1023
+ me("Setup cancelled.");
1024
+ finishCommand(0);
1025
+ }
1026
+ }
1027
+ let localVideoName;
1028
+ let videoHasAudio = true;
1029
+ let sourceFilePath;
1030
+ let videoDuration;
1031
+ let videoSize;
1032
+ if (videoFlag) {
1033
+ const videoPath = resolve(videoFlag);
1034
+ if (!existsSync2(videoPath)) {
1035
+ R.error(`File not found: ${videoFlag}`);
1036
+ me("Setup cancelled.");
1037
+ failCommand();
1038
+ }
1039
+ mkdirSync(destDir, { recursive: true });
1040
+ sourceFilePath = videoPath;
1041
+ const result = await handleVideoFile(videoPath, destDir, true, keepOriginal);
1042
+ localVideoName = result.localVideoName;
1043
+ videoHasAudio = result.meta.hasAudio;
1044
+ videoDuration = result.meta.durationSeconds;
1045
+ videoSize = result.meta;
1046
+ } else if (audioFlag) {
1047
+ const audioPath = resolve(audioFlag);
1048
+ if (!existsSync2(audioPath)) {
1049
+ R.error(`File not found: ${audioFlag}`);
1050
+ me("Setup cancelled.");
1051
+ failCommand();
1052
+ }
1053
+ mkdirSync(destDir, { recursive: true });
1054
+ sourceFilePath = audioPath;
1055
+ copyFileSync(audioPath, resolve(destDir, basename(audioPath)));
1056
+ const { getMediaDurationSeconds } = await import("./transcribe-UJESPBT5.js");
1057
+ videoDuration = getMediaDurationSeconds(audioPath) ?? void 0;
1058
+ R.info(`Audio copied to ${c.accent(basename(audioPath))}`);
1059
+ }
1060
+ if (sourceFilePath) {
1061
+ const transcribeChoice = await ue({
1062
+ message: "Generate captions from audio?",
1063
+ initialValue: true
1064
+ });
1065
+ if (!q(transcribeChoice) && transcribeChoice) {
1066
+ const { findWhisper } = await import("./manager-WA4F2GST.js");
1067
+ const needsInstall = findWhisper() === void 0;
1068
+ if (needsInstall) {
1069
+ R.info(c.dim("whisper-cpp not found \u2014 installing automatically..."));
1070
+ }
1071
+ const spin2 = ft();
1072
+ spin2.start(
1073
+ needsInstall ? "Installing whisper-cpp (this may take a moment)..." : "Preparing transcription..."
1074
+ );
1075
+ try {
1076
+ const { ensureWhisper, ensureModel } = await import("./manager-WA4F2GST.js");
1077
+ await ensureWhisper({
1078
+ onProgress: (msg) => spin2.message(msg)
1079
+ });
1080
+ await ensureModel(initialTranscriptionModel, {
1081
+ onProgress: (msg) => spin2.message(msg)
1082
+ });
1083
+ spin2.message("Transcribing audio...");
1084
+ const { transcribe: runTranscribe } = await import("./transcribe-UJESPBT5.js");
1085
+ const transcribeResult = await runTranscribe(sourceFilePath, destDir, {
1086
+ model: modelFlag,
1087
+ language: languageFlag,
1088
+ onProgress: (msg) => spin2.message(msg)
1089
+ });
1090
+ spin2.stop(
1091
+ c.success(
1092
+ `Transcribed ${transcribeResult.wordCount} words (${transcribeResult.durationSeconds.toFixed(1)}s)`
1093
+ )
1094
+ );
1095
+ } catch (err) {
1096
+ spin2.stop(c.dim(`Transcription skipped: ${err instanceof Error ? err.message : err}`));
1097
+ }
1098
+ }
1099
+ }
1100
+ let templateId;
1101
+ if (exampleFlag || videoFlag || audioFlag) {
1102
+ templateId = resolveScaffoldTemplateId(exampleFlag, Boolean(videoFlag || audioFlag));
1103
+ } else {
1104
+ const allTemplates = await resolveTemplateList();
1105
+ const defaultTemplate = "blank";
1106
+ const templateResult = await Ee({
1107
+ message: "Pick an example",
1108
+ options: allTemplates.map((t) => ({
1109
+ value: t.id,
1110
+ label: t.label,
1111
+ hint: t.source === "remote" ? `${t.hint} (download)` : t.hint
1112
+ })),
1113
+ initialValue: defaultTemplate
1114
+ });
1115
+ if (q(templateResult)) {
1116
+ me("Setup cancelled.");
1117
+ finishCommand(0);
1118
+ }
1119
+ templateId = templateResult;
1120
+ }
1121
+ const spin = ft();
1122
+ const isBundled = BUNDLED_TEMPLATES.some((t) => t.id === templateId);
1123
+ if (!isBundled) {
1124
+ spin.start(`Downloading example ${c.accent(templateId)}...`);
1125
+ }
1126
+ try {
1127
+ const media = {
1128
+ video: localVideoName ? { filename: localVideoName, hasAudio: videoHasAudio } : void 0,
1129
+ audio: audioFlag ? { filename: basename(audioFlag) } : void 0,
1130
+ durationSeconds: videoDuration
1131
+ };
1132
+ await scaffoldProject(
1133
+ destDir,
1134
+ name,
1135
+ templateId,
1136
+ media,
1137
+ tailwind,
1138
+ resolutionPreset ?? clipFrame(templateId, videoSize),
1139
+ args.skill
1140
+ );
1141
+ if (!isBundled) {
1142
+ spin.stop(c.success(`Downloaded ${templateId}`));
1143
+ }
1144
+ } catch (err) {
1145
+ if (!isBundled) {
1146
+ spin.stop(c.error("Download failed"));
1147
+ }
1148
+ R.error(
1149
+ `${err instanceof Error ? err.message : err}
1150
+ ${c.dim("Use --example blank for offline use.")}`
1151
+ );
1152
+ failCommand();
1153
+ }
1154
+ await finishScaffold(destDir, templateId, tailwind);
1155
+ const files = readdirSync(destDir);
1156
+ Se(files.map((f) => c.accent(f)).join("\n"), c.success(`Created ${name}/`));
1157
+ if (!skipSkills) {
1158
+ await keepSkillsCurrent(destDir);
1159
+ }
1160
+ R.info("Opening studio preview...");
1161
+ try {
1162
+ const previewCmd = await import("./preview-EKZ33JOJ.js").then((m) => m.default);
1163
+ await runCommand(previewCmd, { rawArgs: [destDir] });
1164
+ } catch {
1165
+ }
1166
+ }
1167
+ });
1168
+ export {
1169
+ applyResolutionPreset,
1170
+ init_default as default,
1171
+ examples,
1172
+ injectTailwindBrowserScript,
1173
+ nameTooLongMessage,
1174
+ resolveVideoDurationSeconds,
1175
+ transcodeToMp4
1176
+ };