@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
package/LICENSE CHANGED
@@ -1 +1,34 @@
1
+ vfrey License
2
+
1
3
  Copyright (c) 2026 vfrey. All rights reserved.
4
+
5
+ 1. Grant. During the beta, vfrey grants you a free, non-exclusive,
6
+ non-transferable right to install and use this package for your own
7
+ purposes, including making and publishing videos with it.
8
+
9
+ 2. Restrictions. You may not:
10
+ - redistribute this package or any part of it;
11
+ - modify it for the purpose of redistributing it;
12
+ - reverse-engineer it, or use it, to build a product that competes
13
+ with vfrey;
14
+ - sublicense, sell, rent or lend it.
15
+
16
+ 3. Your videos. Videos and files you make with vfrey belong to you.
17
+
18
+ 4. Third-party components. This package includes third-party software that
19
+ keeps its own license. The vendored Framey engine (vendor/framey) is
20
+ Apache-2.0 and based on HeyGen HyperFrames; see vendor/framey/LICENSE and
21
+ vendor/framey/NOTICE. Dependencies installed in node_modules carry their
22
+ own licenses. This license does not change them.
23
+
24
+ 5. No warranty. This package is provided "as is", without warranty of any
25
+ kind, express or implied, including merchantability, fitness for a
26
+ particular purpose and non-infringement. It is beta software.
27
+
28
+ 6. Limitation of liability. To the extent the law allows, vfrey is not
29
+ liable for any claim, damages or other liability arising from the use of
30
+ this package. You are responsible for what you publish and for
31
+ following each platform's rules.
32
+
33
+ 7. Ending. This license ends if you break it. vfrey may end the beta and
34
+ this free grant on notice.
package/README.md CHANGED
@@ -1,5 +1,80 @@
1
- # @vfrey/vfrey
1
+ # vfrey
2
2
 
3
- vfrey makes short vertical videos by asking your own coding agent.
3
+ Make short vertical videos by asking your own coding agent. The agent designs each video as code, so there is no template ceiling, and you own the files.
4
4
 
5
- This package is a placeholder. vfrey is not released on npm yet. See https://vfrey.vercel.app.
5
+ Status: **beta**. Private beta; see [vfrey.vercel.app](https://vfrey.vercel.app).
6
+
7
+ ## Quick start
8
+
9
+ ```bash
10
+ npm create vfrey@latest my-channel
11
+ cd my-channel
12
+ ```
13
+
14
+ > **Note:** during the beta use `npm create vfrey@beta my-channel`. `npx create-vfrey my-channel` does the same thing.
15
+
16
+ Already have a folder? Run `npx @vfrey/vfrey init` in it. Inside a project, `npx vfrey ...` runs that project's own copy. To type `vfrey ...` anywhere, install it once with `npm i -g @vfrey/vfrey`.
17
+
18
+ Open the folder in your coding agent (Claude Code, Codex, Grok, Cursor or Gemini CLI) and ask:
19
+
20
+ > make me a short about how octopuses change color
21
+
22
+ The agent writes the script, designs the scene, renders the video into `videos/`, and shows it to you. To look at your videos and runs yourself:
23
+
24
+ ```bash
25
+ npx vfrey open
26
+ ```
27
+
28
+ ## What you get
29
+
30
+ - **A project folder per channel.** `vfrey.json`, `AGENTS.md`, `CLAUDE.md` and `GEMINI.md` that tell any agent what to do, the vfrey skill for each agent, `scenes/`, `scripts/`, `videos/`, and a private `.vfrey/` data folder.
31
+ - **Readable videos.** `videos/2026-10-26 How octopuses change color.mp4` with the transcript beside it as `.txt`.
32
+ - **A local dashboard** on your machine: a board of runs, a timeline for each one, and the video. `npx vfrey open` starts or reuses it.
33
+ - **Three render engines**: Remotion, Framey (HTML and GSAP) and HyperFrames (when its CLI is installed). 1080x1920 at 30 fps.
34
+ - **Voice and word-timed captions** that follow the spoken words.
35
+ - **An `AI-GENERATED` label burned into every video.** A scene cannot cover it.
36
+ - **Publishing through official APIs** (YouTube, TikTok, Instagram, Facebook) when you add your own keys, always with the platform's AI-disclosure flag set. With no key, nothing is uploaded and the video stays on your machine.
37
+
38
+ ## Works with
39
+
40
+ | Agent | Reads |
41
+ | --- | --- |
42
+ | Claude Code | `CLAUDE.md`, `.claude/skills/vfrey/` |
43
+ | Codex | `AGENTS.md`, `.agents/skills/vfrey/` |
44
+ | Grok | `AGENTS.md`, `.agents/skills/vfrey/` |
45
+ | Cursor | `AGENTS.md`, `.agents/skills/vfrey/` |
46
+ | Gemini CLI | `GEMINI.md`, `.agents/skills/vfrey/` |
47
+
48
+ ## Requirements
49
+
50
+ - Node 22.13 or newer.
51
+ - A voice: macOS speaks with the built-in `say` command. On another system set `TTS_PROVIDER=openai` (paid voice, needs a key) or `TTS_PROVIDER=none` (silent video).
52
+ - Chrome Headless Shell, downloaded on your first render (about 170 MB).
53
+ - A coding agent from the table above. vfrey has no model of its own; you pay for your agent, not per video.
54
+
55
+ Run `npx vfrey doctor` to check your machine.
56
+
57
+ ## Commands an agent uses
58
+
59
+ | Command | What it does |
60
+ | --- | --- |
61
+ | `npx vfrey doctor` | Checks the machine and prints a fix for anything wrong |
62
+ | `npx vfrey scene init DIR` | Writes a starter scene to replace with a design for the idea |
63
+ | `npx vfrey render --scene DIR --engine <id> --script script.json --frame 2.5 out.png` | Looks at one frame before rendering |
64
+ | `npx vfrey tick --now --about "<subject>" --script script.json --scene DIR --engine <id>` | Makes the video |
65
+ | `npx vfrey videos` | Lists your finished videos, newest first |
66
+ | `npx vfrey open` | Opens the dashboard |
67
+ | `npx vfrey engine list` | Shows which engines are ready |
68
+
69
+ `npx vfrey --help` lists everything.
70
+
71
+ ## Links
72
+
73
+ - Docs: https://vfrey.vercel.app/docs
74
+ - Site: https://vfrey.vercel.app
75
+
76
+ Roadmap: scheduled autopilot posting across several channels, then a hosted tier.
77
+
78
+ ## License
79
+
80
+ Proprietary. Free to install and use during the beta. See [LICENSE](LICENSE). Third-party components keep their own licenses.
@@ -0,0 +1,61 @@
1
+ {
2
+ "accounts": [
3
+ {
4
+ "id": "desk",
5
+ "niche": "mortgage lock desks for first-time buyers",
6
+ "language": "en",
7
+ "voices": ["alloy", "nova"],
8
+ "hashtagPool": ["#lockdesk", "#mortgage"],
9
+ "waiveAudioRotation": false,
10
+ "cadence": {
11
+ "timezone": "America/New_York",
12
+ "minHoursBetweenPosts": 20,
13
+ "maxPostsPerDay": 1,
14
+ "windows": ["09:00-11:30", "17:00-19:00"]
15
+ },
16
+ "sources": {
17
+ "rss": ["https://www.federalreserve.gov/feeds/press_all.xml"],
18
+ "subreddits": ["FirstTimeHomeBuyer"],
19
+ "youtubeChannelIds": [],
20
+ "youtubeTrendingRegion": null
21
+ },
22
+ "platforms": {
23
+ "youtube": {
24
+ "enabled": true,
25
+ "privacyStatus": "private",
26
+ "categoryId": "27",
27
+ "madeForKids": false,
28
+ "refreshTokenEnv": "YT_REFRESH_TOKEN",
29
+ "clientIdEnv": "GOOGLE_CLIENT_ID",
30
+ "clientSecretEnv": "GOOGLE_CLIENT_SECRET"
31
+ },
32
+ "tiktok": {
33
+ "enabled": true,
34
+ "privacyLevel": "SELF_ONLY",
35
+ "refreshTokenEnv": "TT_REFRESH_TOKEN",
36
+ "openIdEnv": "TT_OPEN_ID",
37
+ "brandContent": false,
38
+ "brandOrganic": false,
39
+ "disableComment": false
40
+ },
41
+ "instagram": {
42
+ "enabled": false,
43
+ "igUserIdEnv": "IG_USER_ID",
44
+ "accessTokenEnv": "IG_ACCESS_TOKEN",
45
+ "shareToFeed": true
46
+ },
47
+ "facebook": {
48
+ "enabled": false,
49
+ "pageIdEnv": "FB_PAGE_ID",
50
+ "pageTokenEnv": "FB_PAGE_TOKEN"
51
+ }
52
+ },
53
+ "engage": {
54
+ "enabled": true,
55
+ "allowSpicy": true,
56
+ "maxRepliesPerDay": 20,
57
+ "minSecondsBetweenReplies": 45
58
+ }
59
+ }
60
+ ]
61
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "accounts": [
3
+ {
4
+ "id": "desk",
5
+ "niche": "what the vfrey pipeline does on a first run",
6
+ "language": "en",
7
+ "voices": ["alloy"],
8
+ "hashtagPool": ["#vfrey"],
9
+ "waiveAudioRotation": true,
10
+ "cadence": {
11
+ "timezone": "UTC",
12
+ "minHoursBetweenPosts": 0,
13
+ "maxPostsPerDay": 1,
14
+ "windows": []
15
+ },
16
+ "sources": {
17
+ "rss": ["https://www.federalreserve.gov/feeds/press_all.xml"],
18
+ "subreddits": [],
19
+ "youtubeChannelIds": [],
20
+ "youtubeTrendingRegion": null
21
+ },
22
+ "platforms": {
23
+ "youtube": {
24
+ "enabled": true,
25
+ "privacyStatus": "private",
26
+ "categoryId": "27",
27
+ "madeForKids": false,
28
+ "refreshTokenEnv": "YT_REFRESH_TOKEN",
29
+ "clientIdEnv": "GOOGLE_CLIENT_ID",
30
+ "clientSecretEnv": "GOOGLE_CLIENT_SECRET"
31
+ }
32
+ },
33
+ "engage": {
34
+ "enabled": false,
35
+ "allowSpicy": false,
36
+ "maxRepliesPerDay": 0,
37
+ "minSecondsBetweenReplies": 45
38
+ }
39
+ }
40
+ ]
41
+ }
package/bin/vfrey.mjs ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import { spawn } from "node:child_process";
4
+ import { createRequire } from "node:module";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
9
+ const require = createRequire(import.meta.url);
10
+ const tsx = require.resolve("tsx");
11
+ const cli = path.join(root, "src/cli.ts");
12
+
13
+ // .env in the working directory loads only when it exists, so Node prints no "not found" notice.
14
+ // The SQLite experimental warning is silenced too: stdout and stderr carry the command's own output only.
15
+ const envFlags = existsSync(path.resolve(process.cwd(), ".env")) ? ["--env-file=.env"] : [];
16
+ const child = spawn(
17
+ process.execPath,
18
+ ["--experimental-sqlite", "--disable-warning=ExperimentalWarning", ...envFlags, "--import", tsx, cli, ...process.argv.slice(2)],
19
+ { stdio: "inherit", env: process.env },
20
+ );
21
+
22
+ // A stop signal for this process is a stop signal for the command it runs.
23
+ for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
24
+ process.on(signal, () => {
25
+ if (child.exitCode === null && child.signalCode === null) child.kill(signal);
26
+ });
27
+ }
28
+
29
+ child.on("exit", (code, signal) => {
30
+ if (signal) {
31
+ process.removeAllListeners(signal);
32
+ process.kill(process.pid, signal);
33
+ return;
34
+ }
35
+ process.exit(code ?? 1);
36
+ });
@@ -0,0 +1,43 @@
1
+ # Integration tools
2
+
3
+ Engines a coding agent can run on the machine to make a video or a still. The input is code or a file the agent writes. The render happens locally. There is no per-image or per-second generation bill.
4
+
5
+ This is the same class of tool as Remotion. It is not a hosted image model, a video model, or a stock API.
6
+
7
+ ## Pick one
8
+
9
+ | Need | Tool | Language | Output |
10
+ | --- | --- | --- | --- |
11
+ | Narrated or designed React short, the way this repo already renders | [Remotion](video/remotion.md) | React | MP4, PNG still |
12
+ | TypeScript motion graphic, generator style | [Motion Canvas](video/motion-canvas.md) | TypeScript | MP4, image sequence |
13
+ | TypeScript video rendered on your own process | [Revideo](video/revideo.md) | TypeScript | MP4 |
14
+ | Math, diagrams, explainers drawn as code | [Manim](video/manim.md) | Python | MP4 |
15
+ | Cut, join, scale, or mux files that already exist | [FFmpeg](video/ffmpeg.md) | CLI | MP4, WAV, PNG |
16
+ | 3D or a full scene file | [Blender](video/blender.md) | Python | MP4, PNG |
17
+ | A designed still from a layout | [Satori](image/satori.md) | JSX | SVG, then PNG |
18
+ | Resize, composite, or convert a raster or SVG | [Sharp](image/sharp.md) | Node | PNG, WebP |
19
+ | Draw an SVG and export a PNG | [resvg](image/resvg.md) | Node or CLI | PNG |
20
+ | Screenshot HTML you already wrote | [Playwright](image/playwright.md) | Node | PNG |
21
+ | Draw a still in Python | [Pillow](image/pillow.md) | Python | PNG |
22
+
23
+ ## Rules for an agent
24
+
25
+ - Prefer the tool already installed. This repo has Remotion and FFmpeg. Use those before adding a dependency.
26
+ - Write the source, render, then check the file exists and has a duration or a pixel size. Do not claim a render you did not run.
27
+ - A still is an image. A film is a video. Do not render a 90 second MP4 when the task is a cover.
28
+ - Do not send the picture to a paid generation API from this folder. If a tool has a cloud render tier, use the local renderer.
29
+ - Do not put secrets, tokens, or API keys in an example.
30
+
31
+ ## Not in this list
32
+
33
+ These are real tools and the wrong answer for "free, local, like Remotion":
34
+
35
+ - Hosted image and video models. They bill per picture or per second.
36
+ - HyperFrames. It renders HTML locally, and it also meters usage. Check `npx hyperframes usage` before a run. A failed or unknown usage check is not permission to render.
37
+ - Remotion's own cloud render and any Lambda render. The local `renderMedia` path is the one this folder means.
38
+ - Inngest. The server source is public under the Server Side Public License, not an open-source media engine.
39
+ - OpenRouter, Firebase, Mintlify, and the Google Cloud console. Those are services.
40
+
41
+ ## License, said once
42
+
43
+ Local does not always mean free for every company. Remotion is free for an individual and for a for-profit organization of up to 3 employees. A larger company needs a Remotion license. The other tools below name their own license in the tool file. Read it before you ship the output for a client.
@@ -0,0 +1,32 @@
1
+ # Pillow
2
+
3
+ Draws a raster image in Python. Rectangles, text, and pasted logos. No browser and no account.
4
+
5
+ License: MIT-CMU, the Historical Permission Notice, for `python-pillow/Pillow`. It is the maintained fork of PIL.
6
+
7
+ ## Use it when
8
+
9
+ A script already in Python needs a simple still: a solid plate, a label, a diagram of boxes.
10
+
11
+ ## Do not use it when
12
+
13
+ The layout is real CSS, wrapping text, or a web font with kerning you care about. Use Satori or Playwright.
14
+
15
+ ## Example
16
+
17
+ ```python
18
+ from PIL import Image, ImageDraw, ImageFont
19
+
20
+ image = Image.new("RGB", (1080, 1920), "#0f1115")
21
+ draw = ImageDraw.Draw(image)
22
+ font = ImageFont.truetype("/System/Library/Fonts/Supplemental/Arial.ttf", 96)
23
+ draw.text((80, 200), "Hello", fill="#f6f3ec", font=font)
24
+ image.save("cover.png")
25
+ ```
26
+
27
+ The Arial path is macOS. On another machine, pass a font file you shipped in the repo. `ImageFont.load_default()` is tiny and looks wrong at cover size.
28
+
29
+ ## Agent notes
30
+
31
+ - Save, then open the file and check `image.size` is `(1080, 1920)`.
32
+ - Paste a logo with `image.paste(logo, (x, y), logo)` only when the logo has an alpha channel. Without the mask, the corners become a box.
@@ -0,0 +1,33 @@
1
+ # Playwright
2
+
3
+ Opens a local HTML file in a headless browser and saves a screenshot. The design is HTML and CSS. The PNG is the viewport.
4
+
5
+ License: Apache-2.0.
6
+
7
+ Chrome on this machine can also screenshot with `--headless=new --screenshot`. Prefer Playwright when you need a settled load, a font, or a selector. Prefer the Chrome flag only when Playwright is not installed and the page is one file.
8
+
9
+ ## Use it when
10
+
11
+ The still is a web layout: a card, a fake phone, a docs page, a cover built as HTML.
12
+
13
+ ## Do not use it when
14
+
15
+ You need a timeline. A screenshot is one frame.
16
+
17
+ ## Example
18
+
19
+ ```ts
20
+ import {chromium} from "playwright";
21
+
22
+ const browser = await chromium.launch();
23
+ const page = await browser.newPage({viewport: {width: 1080, height: 1920}, deviceScaleFactor: 1});
24
+ await page.goto("file://" + process.cwd() + "/cover.html", {waitUntil: "networkidle"});
25
+ await page.screenshot({path: "cover.png"});
26
+ await browser.close();
27
+ ```
28
+
29
+ ## Agent notes
30
+
31
+ - Set the viewport. A default window is not 1080x1920.
32
+ - `networkidle` matters when the page loads a logo. A shot taken before the image arrives is a broken cover.
33
+ - Do not point `goto` at a site you were not asked to capture.
@@ -0,0 +1,36 @@
1
+ # resvg
2
+
3
+ Renders an SVG file to a PNG. The drawing is the SVG you wrote. The renderer does not redesign it.
4
+
5
+ License: MPL-2.0 for the Rust project `linebender/resvg`. The Node binding `@resvg/resvg-js` follows that package. Read the license if you ship the binding.
6
+
7
+ ## Use it when
8
+
9
+ The picture is an SVG you can write by hand: a logo lockup, an icon, a simple cover.
10
+
11
+ ## Do not use it when
12
+
13
+ The SVG is mostly HTML and CSS layout. Browsers and Satori handle that. resvg handles SVG.
14
+
15
+ ## Example
16
+
17
+ ```ts
18
+ import {Resvg} from "@resvg/resvg-js";
19
+ import {readFileSync, writeFileSync} from "node:fs";
20
+
21
+ const png = new Resvg(readFileSync("cover.svg"), {fitTo: {mode: "width", value: 1080}}).render();
22
+ writeFileSync("cover.png", png.asPng());
23
+ ```
24
+
25
+ The CLI, when the package is installed:
26
+
27
+ ```bash
28
+ npx resvg-js cover.svg cover.png
29
+ ```
30
+
31
+ If that binary name is not the one the installed package exposes, read `package.json` of `@resvg/resvg-js` and use the script it names.
32
+
33
+ ## Agent notes
34
+
35
+ - Give the SVG a `width` and a `height`, or pass `fitTo`. A missing size becomes a surprise.
36
+ - A font used in `<text>` must be installed or passed in `font.fontFiles`. Outlined paths do not need a font.
@@ -0,0 +1,36 @@
1
+ # Satori
2
+
3
+ Turns a JSX tree into an SVG. Pair it with resvg and you get a PNG. The layout is CSS-like. Nothing leaves the machine.
4
+
5
+ License: MPL-2.0 for `vercel/satori`. resvg has its own license. Read both if you ship the libraries, not just a PNG.
6
+
7
+ ## Use it when
8
+
9
+ You need a cover, an Open Graph card, or a title still with real text and a few shapes, and you do not want a browser.
10
+
11
+ ## Do not use it when
12
+
13
+ The image is a frame of a timeline. Render a Remotion still. Satori has no frame clock.
14
+
15
+ ## Example
16
+
17
+ ```tsx
18
+ import satori from "satori";
19
+ import {Resvg} from "@resvg/resvg-js";
20
+ import {writeFileSync} from "node:fs";
21
+
22
+ const svg = await satori(
23
+ <div style={{width: "100%", height: "100%", background: "#0f1115", color: "#f6f3ec", fontSize: 96, padding: 80}}>
24
+ Hello
25
+ </div>,
26
+ {width: 1080, height: 1920, fonts: [{name: "Inter", data: fontBytes, weight: 700}]},
27
+ );
28
+ writeFileSync("cover.png", new Resvg(svg).render().asPng());
29
+ ```
30
+
31
+ You must pass a real font file in `fonts`. Satori does not fall back to a system font. If the text is missing, the font was not loaded.
32
+
33
+ ## Agent notes
34
+
35
+ - Width and height are the image size. Set them. Do not rely on a screenshot scale.
36
+ - Open the PNG after writing it. A successful process exit with an empty file is a failed render.
@@ -0,0 +1,38 @@
1
+ # Sharp
2
+
3
+ A Node library for raster images. It resizes, composites, converts SVG to PNG, and writes WebP. It uses libvips. The work is local.
4
+
5
+ License: Apache-2.0.
6
+
7
+ ## Use it when
8
+
9
+ You already have a PNG, JPG, or SVG and you need another size, a crop, or a format change.
10
+
11
+ ## Do not use it when
12
+
13
+ You still have to design the layout from scratch and the layout is mostly text. Satori or a Playwright screenshot of HTML is the clearer tool.
14
+
15
+ ## Example
16
+
17
+ ```ts
18
+ import sharp from "sharp";
19
+
20
+ await sharp("logo.svg")
21
+ .resize(1080, 1920, {fit: "contain", background: "#0f1115"})
22
+ .png()
23
+ .toFile("cover.png");
24
+ ```
25
+
26
+ Composite a logo onto a plate:
27
+
28
+ ```ts
29
+ await sharp({create: {width: 1080, height: 1920, channels: 4, background: "#0f1115"}})
30
+ .composite([{input: "logo.png", gravity: "centre"}])
31
+ .png()
32
+ .toFile("cover.png");
33
+ ```
34
+
35
+ ## Agent notes
36
+
37
+ - `fit: "contain"` letterboxes. `fit: "cover"` crops. Pick one and say which.
38
+ - Read `cover.png` back, or at least `sharp(file).metadata()`, before you say the size is 1080x1920.
@@ -0,0 +1,34 @@
1
+ # Blender
2
+
3
+ A full 3D scene, rendered with no display. The scene is a `.blend` file or a Python script Blender runs. The render is local.
4
+
5
+ License: GPL. The program is free. A render you make is yours. Linking Blender into a closed app is a different question. Read the GPL before you embed it.
6
+
7
+ ## Use it when
8
+
9
+ The shot is a 3D object, a camera move, or a lighting setup that a 2D composition would fake badly.
10
+
11
+ ## Do not use it when
12
+
13
+ The shot is type, a card, and a logo. That is Remotion. Blender is a large install and a slow render.
14
+
15
+ ## Example
16
+
17
+ ```bash
18
+ blender -b scene.blend -o //frame_ -F PNG -f 1
19
+ blender -b scene.blend -o //shot_ -a
20
+ ```
21
+
22
+ `-b` is background. `-f 1` is one frame. `-a` is the animation. `//` is the path next to the blend file.
23
+
24
+ Drive a scene from Python:
25
+
26
+ ```bash
27
+ blender -b --python shot.py
28
+ ```
29
+
30
+ ## Agent notes
31
+
32
+ - Check that `blender` is on `PATH` before you write a long script. If it is missing, say so. Do not pretend the render ran.
33
+ - One frame first. Then the animation.
34
+ - Name the output. Blender's default path is easy to lose.
@@ -0,0 +1,41 @@
1
+ # FFmpeg
2
+
3
+ The local tool that reads and writes media files. It cuts, joins, scales, overlays a still, and muxes a voice onto a silent picture. It does not invent a scene.
4
+
5
+ License: FFmpeg builds are LGPL or GPL depending on how they were compiled. `ffmpeg -version` shows which. Do not ship a GPL build inside a closed app without reading that line.
6
+
7
+ This machine already has `ffmpeg` and `ffprobe`. The pipeline uses them for voice files.
8
+
9
+ ## Use it when
10
+
11
+ The pictures already exist and you need one file: trim, concat, scale to 1080x1920, or add audio.
12
+
13
+ ## Do not use it when
14
+
15
+ You still have to design the frames. Write those in Remotion, Motion Canvas, or Manim, then come back here to mux.
16
+
17
+ ## Example
18
+
19
+ Silent color plate, three seconds, vertical:
20
+
21
+ ```bash
22
+ ffmpeg -y -f lavfi -i color=c=0x0f1115:s=1080x1920:d=3 -pix_fmt yuv420p out/plate.mp4
23
+ ```
24
+
25
+ Put a voice on a silent MP4 without re-encoding the picture:
26
+
27
+ ```bash
28
+ ffmpeg -y -i picture.mp4 -i voice.wav -c:v copy -c:a aac -shortest out/with-voice.mp4
29
+ ```
30
+
31
+ Duration:
32
+
33
+ ```bash
34
+ ffprobe -v error -show_entries format=duration -of csv=p=0 out/with-voice.mp4
35
+ ```
36
+
37
+ ## Agent notes
38
+
39
+ - `-shortest` ends the file when the shorter input ends. Use it on purpose.
40
+ - `apad=pad_dur=0.28` adds a quiet tail so the last word is not cut. The pipeline voice takes use that.
41
+ - Do not download a media file from a random URL to use as footage.
@@ -0,0 +1,37 @@
1
+ # Manim
2
+
3
+ Python scenes draw shapes, text, and graphs, then play them. Manim Community Edition renders a local MP4. No account.
4
+
5
+ License: MIT for Manim Community (`ManimCommunity/manim`). The original 3b1b Manim is a different repository. Use Community unless the user named the other one.
6
+
7
+ ## Use it when
8
+
9
+ The picture is a diagram, an equation, a geometric proof, or a lesson where shapes move because the code says so.
10
+
11
+ ## Do not use it when
12
+
13
+ The picture is a product UI or a captioned social short in this repo's house style. Use Remotion.
14
+
15
+ ## Example
16
+
17
+ ```python
18
+ from manim import *
19
+
20
+ class Hello(Scene):
21
+ def construct(self):
22
+ title = Text("Hello")
23
+ self.play(Write(title))
24
+ self.wait()
25
+ ```
26
+
27
+ ```bash
28
+ pip install manim
29
+ manim -pql hello.py Hello
30
+ ```
31
+
32
+ `-ql` is a low-quality preview. Drop `p` on a machine with no display. Use `-qh` only when the preview is already right.
33
+
34
+ ## Agent notes
35
+
36
+ - The class name and the file name are both required. `manim file.py Hello` renders the `Hello` class.
37
+ - The MP4 path is printed at the end. Check that path. Do not assume `out/hello.mp4`.
@@ -0,0 +1,37 @@
1
+ # Motion Canvas
2
+
3
+ A TypeScript scene yields animation steps. The editor shows the result while you edit. The CLI renders an image sequence or a video on this machine.
4
+
5
+ License: MIT. Repository: `motion-canvas/motion-canvas`.
6
+
7
+ ## Use it when
8
+
9
+ The piece is a motion graphic or a code explainer and you want a generator (`yield*`) instead of a React frame clock. You do not need this repo's existing Remotion templates.
10
+
11
+ ## Do not use it when
12
+
13
+ The short must live in `src/remotion/` and ship through `npm run tick`. Use Remotion for that.
14
+
15
+ ## Example
16
+
17
+ ```tsx
18
+ import {makeScene2D, Txt} from "@motion-canvas/2d";
19
+ import {createRef} from "@motion-canvas/core";
20
+
21
+ export default makeScene2D(function* (view) {
22
+ const title = createRef<Txt>();
23
+ view.add(<Txt ref={title} text="Hello" fill="#f6f3ec" fontSize={120} />);
24
+ yield* title().scale(1.2, 0.6);
25
+ });
26
+ ```
27
+
28
+ Scaffold a project, then render with that project's CLI. The maintained CLI package is `@motion-canvas/cli`. Read the scaffold's `package.json` for the exact script name before you invent a flag. A typical render is:
29
+
30
+ ```bash
31
+ npx @motion-canvas/cli render --project src/project.ts
32
+ ```
33
+
34
+ ## Agent notes
35
+
36
+ - The preview and the render must use the same project file. A scene that is not registered in the project does not render.
37
+ - Confirm the output file and its duration after the command exits.