egaki 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/dist/cli/cache-utils.d.ts +33 -0
  3. package/dist/cli/cache-utils.d.ts.map +1 -0
  4. package/dist/cli/cache-utils.js +157 -0
  5. package/dist/cli/cached-generate.d.ts +105 -0
  6. package/dist/cli/cached-generate.d.ts.map +1 -0
  7. package/dist/cli/cached-generate.js +208 -0
  8. package/dist/cli/cached-generate.test.d.ts +11 -0
  9. package/dist/cli/cached-generate.test.d.ts.map +1 -0
  10. package/dist/cli/cached-generate.test.js +431 -0
  11. package/dist/cli/cartesia-provider.d.ts +16 -0
  12. package/dist/cli/cartesia-provider.d.ts.map +1 -0
  13. package/dist/cli/cartesia-provider.js +184 -0
  14. package/dist/cli/chatgpt-auth.d.ts.map +1 -0
  15. package/dist/cli/cli.d.ts +4 -0
  16. package/dist/cli/cli.d.ts.map +1 -0
  17. package/dist/cli/cli.js +1329 -0
  18. package/dist/cli/clone-generate.d.ts +26 -0
  19. package/dist/cli/clone-generate.d.ts.map +1 -0
  20. package/dist/cli/clone-generate.js +148 -0
  21. package/dist/{credentials.d.ts → cli/credentials.d.ts} +11 -2
  22. package/dist/cli/credentials.d.ts.map +1 -0
  23. package/dist/{credentials.js → cli/credentials.js} +88 -5
  24. package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
  25. package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
  26. package/dist/cli/elevenlabs-speech-provider.js +199 -0
  27. package/dist/cli/generate.d.ts +140 -0
  28. package/dist/cli/generate.d.ts.map +1 -0
  29. package/dist/cli/generate.js +604 -0
  30. package/dist/cli/generate.test.d.ts +2 -0
  31. package/dist/cli/generate.test.d.ts.map +1 -0
  32. package/dist/cli/generate.test.js +131 -0
  33. package/dist/cli/login.d.ts.map +1 -0
  34. package/dist/{login.js → cli/login.js} +45 -4
  35. package/dist/cli/main.d.ts +3 -0
  36. package/dist/cli/main.d.ts.map +1 -0
  37. package/dist/cli/main.js +7 -0
  38. package/dist/cli/model-catalog.d.ts +141 -0
  39. package/dist/cli/model-catalog.d.ts.map +1 -0
  40. package/dist/cli/model-catalog.js +2135 -0
  41. package/dist/{models.d.ts → cli/models.d.ts} +16 -9
  42. package/dist/cli/models.d.ts.map +1 -0
  43. package/dist/cli/models.js +313 -0
  44. package/dist/cli/open-browser.d.ts.map +1 -0
  45. package/dist/cli/openai-speech-provider.d.ts +3 -0
  46. package/dist/cli/openai-speech-provider.d.ts.map +1 -0
  47. package/dist/cli/openai-speech-provider.js +28 -0
  48. package/dist/cli/separation-generate.d.ts +34 -0
  49. package/dist/cli/separation-generate.d.ts.map +1 -0
  50. package/dist/cli/separation-generate.js +117 -0
  51. package/dist/cli/speech-catalog.d.ts +35 -0
  52. package/dist/cli/speech-catalog.d.ts.map +1 -0
  53. package/dist/cli/speech-catalog.js +195 -0
  54. package/dist/cli/speech-generate.d.ts +86 -0
  55. package/dist/cli/speech-generate.d.ts.map +1 -0
  56. package/dist/cli/speech-generate.js +156 -0
  57. package/dist/cli/speech-models.d.ts +8 -0
  58. package/dist/cli/speech-models.d.ts.map +1 -0
  59. package/dist/cli/speech-models.js +109 -0
  60. package/dist/cli/speech-provider.test.d.ts +2 -0
  61. package/dist/cli/speech-provider.test.d.ts.map +1 -0
  62. package/dist/cli/speech-provider.test.js +197 -0
  63. package/dist/cli/subscription.d.ts.map +1 -0
  64. package/dist/cli/transcription-catalog.d.ts +35 -0
  65. package/dist/cli/transcription-catalog.d.ts.map +1 -0
  66. package/dist/cli/transcription-catalog.js +192 -0
  67. package/dist/cli/transcription-generate.d.ts +62 -0
  68. package/dist/cli/transcription-generate.d.ts.map +1 -0
  69. package/dist/cli/transcription-generate.js +144 -0
  70. package/dist/cli/transcription-models.d.ts +9 -0
  71. package/dist/cli/transcription-models.d.ts.map +1 -0
  72. package/dist/cli/transcription-models.js +100 -0
  73. package/dist/cli/transcription-providers.d.ts +22 -0
  74. package/dist/cli/transcription-providers.d.ts.map +1 -0
  75. package/dist/cli/transcription-providers.js +290 -0
  76. package/dist/cli/video-model-catalog.d.ts +2 -0
  77. package/dist/cli/video-model-catalog.d.ts.map +1 -0
  78. package/dist/cli/video-model-catalog.js +5 -0
  79. package/dist/cli/xai-auth.d.ts +29 -0
  80. package/dist/cli/xai-auth.d.ts.map +1 -0
  81. package/dist/cli/xai-auth.js +325 -0
  82. package/dist/vite/angled-screen.d.ts +57 -0
  83. package/dist/vite/angled-screen.d.ts.map +1 -0
  84. package/dist/vite/angled-screen.js +115 -0
  85. package/dist/vite/app.d.ts +51 -0
  86. package/dist/vite/app.d.ts.map +1 -0
  87. package/dist/vite/app.js +150 -0
  88. package/dist/vite/bands-shader.d.ts +47 -0
  89. package/dist/vite/bands-shader.d.ts.map +1 -0
  90. package/dist/vite/bands-shader.js +267 -0
  91. package/dist/vite/code-block.d.ts +107 -0
  92. package/dist/vite/code-block.d.ts.map +1 -0
  93. package/dist/vite/code-block.js +641 -0
  94. package/dist/vite/components.d.ts +36 -0
  95. package/dist/vite/components.d.ts.map +1 -0
  96. package/dist/vite/components.js +113 -0
  97. package/dist/vite/dispersion-rings-shader.d.ts +44 -0
  98. package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
  99. package/dist/vite/dispersion-rings-shader.js +282 -0
  100. package/dist/vite/easing-curves.d.ts +129 -0
  101. package/dist/vite/easing-curves.d.ts.map +1 -0
  102. package/dist/vite/easing-curves.js +584 -0
  103. package/dist/vite/easing-curves.test.d.ts +2 -0
  104. package/dist/vite/easing-curves.test.d.ts.map +1 -0
  105. package/dist/vite/easing-curves.test.js +200 -0
  106. package/dist/vite/generated-media-client.d.ts +35 -0
  107. package/dist/vite/generated-media-client.d.ts.map +1 -0
  108. package/dist/vite/generated-media-client.js +76 -0
  109. package/dist/vite/keyframes.d.ts +129 -0
  110. package/dist/vite/keyframes.d.ts.map +1 -0
  111. package/dist/vite/keyframes.js +194 -0
  112. package/dist/vite/layout-editor.d.ts +45 -0
  113. package/dist/vite/layout-editor.d.ts.map +1 -0
  114. package/dist/vite/layout-editor.js +587 -0
  115. package/dist/vite/layout-transition.d.ts +136 -0
  116. package/dist/vite/layout-transition.d.ts.map +1 -0
  117. package/dist/vite/layout-transition.js +581 -0
  118. package/dist/vite/liquid-gradient-shader.d.ts +62 -0
  119. package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
  120. package/dist/vite/liquid-gradient-shader.js +413 -0
  121. package/dist/vite/mdx-client.d.ts +15 -0
  122. package/dist/vite/mdx-client.d.ts.map +1 -0
  123. package/dist/vite/mdx-client.js +265 -0
  124. package/dist/vite/mdx-parse.d.ts +102 -0
  125. package/dist/vite/mdx-parse.d.ts.map +1 -0
  126. package/dist/vite/mdx-parse.js +251 -0
  127. package/dist/vite/mdx-provided-components.d.ts +18 -0
  128. package/dist/vite/mdx-provided-components.d.ts.map +1 -0
  129. package/dist/vite/mdx-provided-components.js +14 -0
  130. package/dist/vite/mdx-video.d.ts +327 -0
  131. package/dist/vite/mdx-video.d.ts.map +1 -0
  132. package/dist/vite/mdx-video.js +596 -0
  133. package/dist/vite/mdx-video.test.d.ts +9 -0
  134. package/dist/vite/mdx-video.test.d.ts.map +1 -0
  135. package/dist/vite/mdx-video.test.js +1945 -0
  136. package/dist/vite/media-components.d.ts +45 -0
  137. package/dist/vite/media-components.d.ts.map +1 -0
  138. package/dist/vite/media-components.js +355 -0
  139. package/dist/vite/media-duration-store.d.ts +66 -0
  140. package/dist/vite/media-duration-store.d.ts.map +1 -0
  141. package/dist/vite/media-duration-store.js +204 -0
  142. package/dist/vite/player-page.d.ts +35 -0
  143. package/dist/vite/player-page.d.ts.map +1 -0
  144. package/dist/vite/player-page.js +720 -0
  145. package/dist/vite/render-client.d.ts +18 -0
  146. package/dist/vite/render-client.d.ts.map +1 -0
  147. package/dist/vite/render-client.js +67 -0
  148. package/dist/vite/sdk.d.ts +221 -0
  149. package/dist/vite/sdk.d.ts.map +1 -0
  150. package/dist/vite/sdk.js +355 -0
  151. package/dist/vite/server-components.d.ts +55 -0
  152. package/dist/vite/server-components.d.ts.map +1 -0
  153. package/dist/vite/server-components.js +156 -0
  154. package/dist/vite/server-mdx.d.ts +74 -0
  155. package/dist/vite/server-mdx.d.ts.map +1 -0
  156. package/dist/vite/server-mdx.js +259 -0
  157. package/dist/vite/shader-renderer.d.ts +48 -0
  158. package/dist/vite/shader-renderer.d.ts.map +1 -0
  159. package/dist/vite/shader-renderer.js +411 -0
  160. package/dist/vite/store-hooks.d.ts +12 -0
  161. package/dist/vite/store-hooks.d.ts.map +1 -0
  162. package/dist/vite/store-hooks.js +93 -0
  163. package/dist/vite/store.d.ts +75 -0
  164. package/dist/vite/store.d.ts.map +1 -0
  165. package/dist/vite/store.js +52 -0
  166. package/dist/vite/store.test.d.ts +6 -0
  167. package/dist/vite/store.test.d.ts.map +1 -0
  168. package/dist/vite/store.test.js +172 -0
  169. package/dist/vite/tweakpane-hook.d.ts +94 -0
  170. package/dist/vite/tweakpane-hook.d.ts.map +1 -0
  171. package/dist/vite/tweakpane-hook.js +450 -0
  172. package/dist/vite/vite-plugin.d.ts +28 -0
  173. package/dist/vite/vite-plugin.d.ts.map +1 -0
  174. package/dist/vite/vite-plugin.js +538 -0
  175. package/dist/vite/wave-gradient-shader.d.ts +41 -0
  176. package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
  177. package/dist/vite/wave-gradient-shader.js +207 -0
  178. package/package.json +103 -25
  179. package/skills/egaki/SKILL.md +162 -1
  180. package/src/cli/cache-utils.ts +169 -0
  181. package/src/cli/cached-generate.test.ts +531 -0
  182. package/src/cli/cached-generate.ts +348 -0
  183. package/src/cli/cartesia-provider.ts +249 -0
  184. package/src/cli/cli.ts +1818 -0
  185. package/src/cli/clone-generate.ts +202 -0
  186. package/src/{credentials.ts → cli/credentials.ts} +90 -7
  187. package/src/cli/elevenlabs-speech-provider.ts +243 -0
  188. package/src/cli/generate.test.ts +166 -0
  189. package/src/cli/generate.ts +912 -0
  190. package/src/{login.ts → cli/login.ts} +48 -3
  191. package/src/cli/main.ts +8 -0
  192. package/src/cli/model-catalog.ts +2336 -0
  193. package/src/cli/models.ts +408 -0
  194. package/src/cli/openai-speech-provider.ts +34 -0
  195. package/src/cli/separation-generate.ts +187 -0
  196. package/src/cli/speech-catalog.ts +253 -0
  197. package/src/cli/speech-generate.ts +275 -0
  198. package/src/cli/speech-models.ts +146 -0
  199. package/src/cli/speech-provider.test.ts +226 -0
  200. package/src/cli/transcription-catalog.ts +250 -0
  201. package/src/cli/transcription-generate.ts +214 -0
  202. package/src/cli/transcription-models.ts +136 -0
  203. package/src/cli/transcription-providers.ts +427 -0
  204. package/src/cli/video-model-catalog.ts +14 -0
  205. package/src/cli/xai-auth.ts +396 -0
  206. package/src/vite/angled-screen.tsx +214 -0
  207. package/src/vite/app.tsx +197 -0
  208. package/src/vite/bands-shader.tsx +319 -0
  209. package/src/vite/code-block.tsx +939 -0
  210. package/src/vite/components.tsx +278 -0
  211. package/src/vite/dispersion-rings-shader.tsx +331 -0
  212. package/src/vite/easing-curves.test.ts +232 -0
  213. package/src/vite/easing-curves.ts +743 -0
  214. package/src/vite/generated-media-client.tsx +121 -0
  215. package/src/vite/keyframes.tsx +347 -0
  216. package/src/vite/layout-editor.tsx +709 -0
  217. package/src/vite/layout-transition.tsx +706 -0
  218. package/src/vite/liquid-gradient-shader.tsx +474 -0
  219. package/src/vite/mdx-client.tsx +420 -0
  220. package/src/vite/mdx-parse.ts +343 -0
  221. package/src/vite/mdx-provided-components.ts +19 -0
  222. package/src/vite/mdx-video.test.tsx +2219 -0
  223. package/src/vite/mdx-video.tsx +976 -0
  224. package/src/vite/media-components.tsx +473 -0
  225. package/src/vite/media-duration-store.ts +225 -0
  226. package/src/vite/motion-timing.ts +194 -0
  227. package/src/vite/player-page.tsx +1107 -0
  228. package/src/vite/render-client.ts +84 -0
  229. package/src/vite/sdk.ts +598 -0
  230. package/src/vite/server-components.tsx +241 -0
  231. package/src/vite/server-mdx.ts +285 -0
  232. package/src/vite/shader-renderer.tsx +535 -0
  233. package/src/vite/store-hooks.ts +117 -0
  234. package/src/vite/store.test.ts +202 -0
  235. package/src/vite/store.ts +115 -0
  236. package/src/vite/styles.css +21 -0
  237. package/src/vite/tweakpane-hook.tsx +593 -0
  238. package/src/vite/virtual-modules.d.ts +30 -0
  239. package/src/vite/vite-plugin.ts +584 -0
  240. package/src/vite/wave-gradient-shader.tsx +253 -0
  241. package/README.md +0 -266
  242. package/dist/antigravity-auth.d.ts +0 -15
  243. package/dist/antigravity-auth.d.ts.map +0 -1
  244. package/dist/antigravity-auth.js +0 -544
  245. package/dist/antigravity-image.d.ts +0 -11
  246. package/dist/antigravity-image.d.ts.map +0 -1
  247. package/dist/antigravity-image.js +0 -285
  248. package/dist/chatgpt-auth.d.ts.map +0 -1
  249. package/dist/cli.d.ts +0 -3
  250. package/dist/cli.d.ts.map +0 -1
  251. package/dist/cli.js +0 -968
  252. package/dist/credentials.d.ts.map +0 -1
  253. package/dist/gateway-model-candidates.generated.d.ts +0 -11
  254. package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
  255. package/dist/gateway-model-candidates.generated.js +0 -64
  256. package/dist/login.d.ts.map +0 -1
  257. package/dist/model-catalog.d.ts +0 -42
  258. package/dist/model-catalog.d.ts.map +0 -1
  259. package/dist/model-catalog.js +0 -1001
  260. package/dist/models.d.ts.map +0 -1
  261. package/dist/models.js +0 -246
  262. package/dist/open-browser.d.ts.map +0 -1
  263. package/dist/subscription.d.ts.map +0 -1
  264. package/dist/video-model-catalog.d.ts +0 -52
  265. package/dist/video-model-catalog.d.ts.map +0 -1
  266. package/dist/video-model-catalog.js +0 -306
  267. package/src/cli.ts +0 -1378
  268. package/src/model-catalog.ts +0 -1077
  269. package/src/models.ts +0 -309
  270. package/src/video-model-catalog.ts +0 -363
  271. /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
  272. /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
  273. /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
  274. /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
  275. /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
  276. /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
  277. /package/dist/{subscription.js → cli/subscription.js} +0 -0
  278. /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
  279. /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
  280. /package/src/{subscription.ts → cli/subscription.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,194 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.7.0
6
+
7
+ 1. **MDX video framework** — write video scenes in MDX files, preview in a browser-based player, and export to MP4 via in-browser WebCodecs rendering. Each `#` heading becomes a timed section. Animation primitives (`Opacity`, `Scale`, `TranslateX`, `TranslateY`, `Blur`) handle motion with composable enter/exit animations:
8
+
9
+ ```mdx
10
+ ---
11
+ fps: 30
12
+ bpm: 120
13
+ ---
14
+
15
+ <Audio src="/soundtrack.mp3" />
16
+
17
+ # Intro duration=3s
18
+
19
+ <TranslateX from={-140} to={0} duration={0.7 * FPS}>
20
+ <div style={{ fontSize: 72, fontWeight: 900, color: 'white' }}>Hello</div>
21
+ </TranslateX>
22
+
23
+ # Scene Two duration=8beats
24
+
25
+ <Opacity from={0} to={1} duration={2 * BEAT}>
26
+ <div style={{ fontSize: 48 }}>Built with egaki</div>
27
+ </Opacity>
28
+ ```
29
+
30
+ Install the Vite plugin (`egaki/vite`), point it at your `.mdx` entry, and run `vite dev`. Heading durations support `s` (seconds), `beats` (from frontmatter `bpm`), and `frames` units. `FPS` and `BEAT` are available as scope variables in MDX expressions.
31
+
32
+ 2. **`egaki speech` command** — text-to-speech generation with OpenAI, ElevenLabs, and Cartesia providers:
33
+
34
+ ```bash
35
+ egaki speech "Hello, welcome to egaki!" -o hello.mp3
36
+ egaki speech "Breaking news" -m gpt-4o-mini-tts --instructions "News anchor tone"
37
+ egaki speech "Smooth narration" -m sonic-3.5 --voice <voice-id> --speed 0.8
38
+ cat script.txt | egaki speech --stdin -o narration.mp3
39
+ ```
40
+
41
+ 3. **`egaki transcribe` command** — speech-to-text with word-level timestamps from OpenAI, ElevenLabs, Deepgram, Groq, and Cartesia:
42
+
43
+ ```bash
44
+ egaki transcribe recording.mp3 -m whisper-1
45
+ egaki transcribe podcast.mp3 -m ink-whisper # Cartesia, cheapest
46
+ egaki transcribe interview.wav --stdout
47
+ ```
48
+
49
+ 4. **`egaki demucs` command** — audio stem separation via fal.ai (no local torch needed):
50
+
51
+ ```bash
52
+ egaki demucs song.mp3 --stems vocals,drums,bass,other
53
+ egaki demucs song.mp3 --stems vocals -o stems/
54
+ ```
55
+
56
+ 5. **`egaki voice clone` command** — clone a voice from audio for use with `egaki speech`:
57
+
58
+ ```bash
59
+ egaki voice clone vocals.mp3 --name "Narrator"
60
+ egaki voice clone clip.mp3 --name "Speaker" --provider elevenlabs --remove-background-noise
61
+ egaki speech "Hello" --voice <voice-id>
62
+ ```
63
+
64
+ 6. **`<Server>` RSC slots in MDX** — mark subtrees as React Server Components with `<Server>`. Children render server-side (async, fs/API access) and stream into the client tree:
65
+
66
+ ```mdx
67
+ import { TextToSpeech } from 'egaki/text-to-speech'
68
+
69
+ # Narrated Scene duration=5s
70
+
71
+ <Server>
72
+ <TextToSpeech text="This narration is generated at dev time." />
73
+ </Server>
74
+ ```
75
+
76
+ Files with `.server.tsx` extension are auto-wrapped in `<Server>` when imported into MDX.
77
+
78
+ 7. **`GeneratedImage`, `GeneratedVideo`, `GeneratedSpeech` server components** — AI-generated media with filesystem caching and deduplication. Generate once, cache forever:
79
+
80
+ ```tsx
81
+ // hero.server.tsx
82
+ import { GeneratedImage } from 'egaki/generate-media'
83
+
84
+ export async function Hero() {
85
+ return <GeneratedImage prompt="magical forest" model="imagen-4.0-generate-001" />
86
+ }
87
+ ```
88
+
89
+ 8. **LayoutTransition FLIP animations** — elements animate from their position in the previous section to the new position using FLIP transforms. Supports cross-section and intra-scene transitions with `showFrom`/`showUpTo`:
90
+
91
+ ```mdx
92
+ # Scene 1 duration=3s
93
+ <LayoutTransition id="title">**Hello**</LayoutTransition>
94
+
95
+ # Scene 2 duration=3s
96
+ <LayoutTransition id="title" duration={25} bounce={0.2}>**Hello**</LayoutTransition>
97
+ ```
98
+
99
+ 9. **WebGL shader components** — `BandsShader`, `WaveGradientShader`, `LiquidGradientShader`, `DispersionRingsShader` ported from Framer with full tweakpane integration. All props are exposed as live sliders and color pickers.
100
+
101
+ 10. **Tweakpane integration** — `useTweakpane(label, schema)` registers live-editable parameters in a shared pane. Components show/hide their controls based on visibility. A "Copy changes" button exports all tweaked values as structured markdown.
102
+
103
+ 11. **Framer Motion (`motion/react`) integration** — auto-detected when installed. `motion.div`, springs, variants, and staggered children work inside MDX sections with frame-deterministic rendering and backward scrubbing support.
104
+
105
+ 12. **Easing curve engine** — ported from Jitter with 14 continuous preset functions (`smoothEasing`, `bounceEasing`, `overshootEasing`, `impulseOvershoot`, etc.) that accept any intensity 0-100. `cubicBezier()` from `egaki/video` attaches `BEZIER_POINTS` metadata for tweakpane editing:
106
+
107
+ ```tsx
108
+ import { EASE, smoothEasing, cubicBezier } from 'egaki/video'
109
+ const x = interpolate(frame, [0, 60], [0, 500], { easing: EASE.smooth })
110
+ ```
111
+
112
+ 13. **`CodeBlock` component** — syntax-highlighted code with shiki and ray.so themes, built into MDX scope.
113
+
114
+ 14. **`Fill` component** — full-frame layer like `AbsoluteFill` but children stretch horizontally and center vertically. Available in MDX without imports.
115
+
116
+ 15. **`inline` and `style` props on animation primitives** — `inline` wraps in a plain `<div>` instead of full-frame `<Fill>`, so animated elements participate in flex/grid layout. `style` adds CSS to the wrapper.
117
+
118
+ 16. **Auto-duration from media** — sections without explicit `duration` infer their length from the longest `<Audio>` or `<Video>` element inside them.
119
+
120
+ 17. **Player redesign** — right sidebar layout, floating toolbar with playback rate control, keyboard shortcuts (J/K/L scrub, space play/pause), video trim controls, and cubic bezier blade for easing editing.
121
+
122
+ 18. **Agent SDK (`window.egakiSDK`)** — programmatic control from Playwriter. Screenshot frames, export video segments, get composition info, filmstrip grid rendering, and element position mapping.
123
+
124
+ 19. **Programmatic `egaki/generate` API** — import `generateImage`, `generateVideo`, `generateSpeech` directly from TypeScript without the CLI.
125
+
126
+ 20. **Custom composition dimensions** — `width` and `height` in MDX frontmatter override the default 1920x1080. `scale` frontmatter field controls pixel density.
127
+
128
+ 21. **Multi-entry MDX** — all `.mdx` files in the project root are served as separate routes, not just the configured entry.
129
+
130
+ 22. **MDX LSP autocomplete** — built-in components get prop autocomplete in `.mdx` files via `@mdx-js/typescript-plugin` and auto-generated `egaki-env.d.ts`.
131
+
132
+ 23. **Breaking: animation primitives replaced** — the 8 previous animation wrappers (`FadeIn`, `SlideIn`, `ScaleIn`, `FadeOut`, etc.) are replaced by 5 composable primitives (`Opacity`, `Scale`, `TranslateX`, `TranslateY`, `Blur`). Enter vs exit is inferred from `startInFrames` sign. Nest them to compose animations.
133
+
134
+ 24. **Breaking: `gapBefore`/`gapAfter` replaced with `startInFrames`** — `<Audio>` and `<Video>` now use `startInFrames` (positive = delay from section start, negative = offset from section end).
135
+
136
+ ## 0.6.0
137
+
138
+ 1. **xAI provider with Grok image and video generation** — generate images and videos using xAI's Aurora and Grok models. Two auth paths: direct API key via `XAI_API_KEY` or Grok Build OAuth browser flow:
139
+
140
+ ```bash
141
+ # Direct API key
142
+ egaki login --provider xai --key xai-xxx
143
+
144
+ # OAuth (opens browser)
145
+ egaki login --provider xai-oauth
146
+
147
+ # Generate images
148
+ egaki image "cyberpunk cityscape at dusk" -m grok-imagine-image -o city.png
149
+
150
+ # Generate videos
151
+ egaki video "a cat playing piano" -m grok-imagine-video -o cat.mp4
152
+ ```
153
+
154
+ Auth priority: explicit `XAI_API_KEY` > xAI OAuth > stored xai key > egaki gateway.
155
+
156
+ 2. **New CLI flags for provider-specific options** — control quality, resolution, output format, and more per-provider:
157
+
158
+ ```bash
159
+ # Quality and resolution (xAI)
160
+ egaki image "portrait" -m grok-imagine-image --quality high --resolution 2k
161
+
162
+ # Output format
163
+ egaki image "logo" -m grok-imagine-image --output-format png
164
+
165
+ # Negative prompts (Fal models)
166
+ egaki image "landscape" -m fal-ai/flux-pro/v1.1 --negative-prompt "blurry, low quality"
167
+
168
+ # Video modes (xAI): edit, extend, reference-to-video
169
+ egaki video "slow zoom out" -m grok-imagine-video --mode extend-video --input clip.mp4
170
+ egaki video "a person walking" -m grok-imagine-video --mode reference-to-video --reference-images ref1.png ref2.png
171
+ ```
172
+
173
+ Flag descriptions are auto-derived from the model catalog so `--help` shows valid values per provider.
174
+
175
+ 3. **Local file upload for video editing and reference images** — `--input` and `--reference-images` on the video command now accept local file paths. Files are uploaded to a temporary R2 bucket (auto-expires after 2 days) and the URL is passed to the provider:
176
+
177
+ ```bash
178
+ # Edit a local video file
179
+ egaki video "add lens flare" -m grok-imagine-video --mode edit-video --input local-clip.mp4
180
+
181
+ # Reference images from disk
182
+ egaki video "person walking in park" -m grok-imagine-video --mode reference-to-video --reference-images photo1.jpg photo2.jpg
183
+ ```
184
+
185
+ The `--video-url` flag was removed; `--input` now handles both local files and URLs depending on the mode.
186
+
187
+ 4. **Unified model catalog** — all image and video model definitions (provider, pricing, features, provider options) now live in a single `model-catalog.ts` file. Provider option schemas are sourced directly from `@ai-sdk/*` package types with URL comments pointing to upstream docs for easy verification.
188
+
189
+ 5. **Type-safe provider options** — provider option objects passed to the AI SDK now use `satisfies` with the actual SDK types, catching mismatches at compile time instead of runtime.
190
+
191
+ 6. **Fixed OAuth race condition** — the xAI OAuth callback server is now resilient to state mismatches from stale browser tabs or retried requests, preventing silent auth failures.
192
+
5
193
  ## 0.5.0
6
194
 
7
195
  1. **Interactive model picker** — omitting `--model` now shows a select prompt with popular models instead of silently using a default:
@@ -0,0 +1,33 @@
1
+ /** Set the project root directory. Called by the Vite plugin on startup. */
2
+ export declare function setProjectRoot(root: string): void;
3
+ /** Get the project root directory. Falls back to cwd if not set. */
4
+ export declare function getProjectRoot(): string;
5
+ /** Deterministic JSON from a value: keys sorted recursively, undefined
6
+ * values stripped. Safe for nested objects and arrays. */
7
+ export declare function stableJsonKey(value: unknown): string;
8
+ /** First 8 hex chars of sha256. */
9
+ export declare function hashKey(input: string | Uint8Array): string;
10
+ /** First ~40 chars of text, kebab-cased, filesystem-safe. */
11
+ export declare function promptPrefix(text: string): string;
12
+ export declare function extensionFromMediaType(mediaType: string): string;
13
+ /** Returns the generated files directory for a given namespace.
14
+ * Creates the directory if it doesn't exist. */
15
+ export declare function generatedDir(namespace: string): string;
16
+ /** Find an existing cached file by hash in the generated directory.
17
+ * Also checks the stale/ subfolder — if found there, restores it. */
18
+ export declare function findCachedFile(dir: string, hash: string): string | undefined;
19
+ /** Find a previous generation with the same prompt prefix (different hash)
20
+ * that can serve as fallback while a new generation is in progress. */
21
+ export declare function findFallbackFile(dir: string, prefix: string, currentHash: string): {
22
+ filename: string;
23
+ inStale: boolean;
24
+ } | undefined;
25
+ /** Move a specific file into the stale/ subfolder of its directory. */
26
+ export declare function moveFileToStale(dir: string, fallback: {
27
+ filename: string;
28
+ inStale: boolean;
29
+ }): void;
30
+ export declare const generationQueue: Map<string, Promise<any>>;
31
+ /** Format key params for logging, omitting undefined values and the _type field. */
32
+ export declare function formatKeyParams(params: Record<string, unknown>): string;
33
+ //# sourceMappingURL=cache-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-utils.d.ts","sourceRoot":"","sources":["../../src/cli/cache-utils.ts"],"names":[],"mappings":"AAoBA,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,QAE1C;AAED,oEAAoE;AACpE,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAMD;2DAC2D;AAC3D,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAaD,mCAAmC;AACnC,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAE1D;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASjD;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAehE;AAMD;iDACiD;AACjD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKtD;AAMD;sEACsE;AACtE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAe5E;AAED;wEACwE;AACxE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAYrI;AAMD,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,QAU5F;AAOD,eAAO,MAAM,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAC0B,CAAA;AAEhF,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAKvE"}
@@ -0,0 +1,157 @@
1
+ // Shared caching utilities for egaki generate functions.
2
+ //
3
+ // Provides deterministic cache keys, file lookup, deduplication queues,
4
+ // and stale file management. Used by the cached variants of generateImage,
5
+ // generateSpeech, generateVideo, and transcribeAudio.
6
+ //
7
+ // The project root (for locating public/generated/) is set via setProjectRoot()
8
+ // at startup. In Vite context, server-components.tsx sets it from the virtual
9
+ // module. Falls back to process.cwd() if not set.
10
+ import { createHash } from 'node:crypto';
11
+ import fs from 'node:fs';
12
+ import path from 'node:path';
13
+ // ---------------------------------------------------------------------------
14
+ // Project root
15
+ // ---------------------------------------------------------------------------
16
+ let _projectRoot;
17
+ /** Set the project root directory. Called by the Vite plugin on startup. */
18
+ export function setProjectRoot(root) {
19
+ _projectRoot = root;
20
+ }
21
+ /** Get the project root directory. Falls back to cwd if not set. */
22
+ export function getProjectRoot() {
23
+ return _projectRoot ?? process.cwd();
24
+ }
25
+ // ---------------------------------------------------------------------------
26
+ // Deterministic cache keys
27
+ // ---------------------------------------------------------------------------
28
+ /** Deterministic JSON from a value: keys sorted recursively, undefined
29
+ * values stripped. Safe for nested objects and arrays. */
30
+ export function stableJsonKey(value) {
31
+ return JSON.stringify(sortValue(value));
32
+ }
33
+ function sortValue(value) {
34
+ if (Array.isArray(value))
35
+ return value.map(sortValue);
36
+ if (!value || typeof value !== 'object')
37
+ return value;
38
+ return Object.fromEntries(Object.entries(value)
39
+ .filter(([, v]) => v !== undefined)
40
+ .sort(([a], [b]) => a.localeCompare(b))
41
+ .map(([k, v]) => [k, sortValue(v)]));
42
+ }
43
+ /** First 8 hex chars of sha256. */
44
+ export function hashKey(input) {
45
+ return createHash('sha256').update(input).digest('hex').slice(0, 8);
46
+ }
47
+ /** First ~40 chars of text, kebab-cased, filesystem-safe. */
48
+ export function promptPrefix(text) {
49
+ const slug = text
50
+ .toLowerCase()
51
+ .replace(/[^a-z0-9\s-]/g, '')
52
+ .trim()
53
+ .replace(/\s+/g, '-')
54
+ .slice(0, 40)
55
+ .replace(/-$/, '');
56
+ return slug || 'generated';
57
+ }
58
+ export function extensionFromMediaType(mediaType) {
59
+ const map = {
60
+ 'image/png': '.png',
61
+ 'image/jpeg': '.jpg',
62
+ 'image/webp': '.webp',
63
+ 'video/mp4': '.mp4',
64
+ 'video/webm': '.webm',
65
+ 'audio/mpeg': '.mp3',
66
+ 'audio/wav': '.wav',
67
+ 'audio/opus': '.opus',
68
+ 'audio/ogg': '.ogg',
69
+ 'audio/aac': '.aac',
70
+ 'audio/flac': '.flac',
71
+ };
72
+ return map[mediaType] || '.bin';
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Generated directory management
76
+ // ---------------------------------------------------------------------------
77
+ /** Returns the generated files directory for a given namespace.
78
+ * Creates the directory if it doesn't exist. */
79
+ export function generatedDir(namespace) {
80
+ const root = getProjectRoot();
81
+ const dir = path.join(root, 'public', 'generated', namespace);
82
+ fs.mkdirSync(dir, { recursive: true });
83
+ return dir;
84
+ }
85
+ // ---------------------------------------------------------------------------
86
+ // File lookup
87
+ // ---------------------------------------------------------------------------
88
+ /** Find an existing cached file by hash in the generated directory.
89
+ * Also checks the stale/ subfolder — if found there, restores it. */
90
+ export function findCachedFile(dir, hash) {
91
+ try {
92
+ const found = fs.readdirSync(dir).find((f) => f.includes(hash));
93
+ if (found)
94
+ return found;
95
+ }
96
+ catch { /* empty */ }
97
+ try {
98
+ const staleDir = path.join(dir, 'stale');
99
+ const inStale = fs.readdirSync(staleDir).find((f) => f.includes(hash));
100
+ if (inStale) {
101
+ fs.renameSync(path.join(staleDir, inStale), path.join(dir, inStale));
102
+ console.log(`[egaki] restored from stale: ${inStale}`);
103
+ return inStale;
104
+ }
105
+ }
106
+ catch { /* empty */ }
107
+ return undefined;
108
+ }
109
+ /** Find a previous generation with the same prompt prefix (different hash)
110
+ * that can serve as fallback while a new generation is in progress. */
111
+ export function findFallbackFile(dir, prefix, currentHash) {
112
+ const match = (f) => f.startsWith(prefix + '-') && !f.includes(currentHash);
113
+ try {
114
+ const inDir = fs.readdirSync(dir).find(match);
115
+ if (inDir)
116
+ return { filename: inDir, inStale: false };
117
+ }
118
+ catch { /* empty */ }
119
+ try {
120
+ const staleDir = path.join(dir, 'stale');
121
+ const inStale = fs.readdirSync(staleDir).find(match);
122
+ if (inStale)
123
+ return { filename: inStale, inStale: true };
124
+ }
125
+ catch { /* empty */ }
126
+ return undefined;
127
+ }
128
+ // ---------------------------------------------------------------------------
129
+ // Stale file management
130
+ // ---------------------------------------------------------------------------
131
+ /** Move a specific file into the stale/ subfolder of its directory. */
132
+ export function moveFileToStale(dir, fallback) {
133
+ if (fallback.inStale)
134
+ return;
135
+ const src = path.join(dir, fallback.filename);
136
+ const staleDir = path.join(dir, 'stale');
137
+ try {
138
+ if (!fs.existsSync(src))
139
+ return;
140
+ fs.mkdirSync(staleDir, { recursive: true });
141
+ fs.renameSync(src, path.join(staleDir, fallback.filename));
142
+ console.log(`[egaki] moved stale: ${fallback.filename} → stale/`);
143
+ }
144
+ catch { /* race with another rename, safe to ignore */ }
145
+ }
146
+ // ---------------------------------------------------------------------------
147
+ // Generation queue — deduplicates concurrent calls with the same cache key.
148
+ // Stored on globalThis so in-flight promises survive Vite HMR module reloads.
149
+ // ---------------------------------------------------------------------------
150
+ export const generationQueue = globalThis.__egakiGenerationQueue ??= new Map();
151
+ /** Format key params for logging, omitting undefined values and the _type field. */
152
+ export function formatKeyParams(params) {
153
+ const entries = Object.entries(params)
154
+ .filter(([k, v]) => v !== undefined && k !== '_type')
155
+ .map(([k, v]) => `${k}=${typeof v === 'string' ? v : JSON.stringify(v)}`);
156
+ return entries.join(', ');
157
+ }
@@ -0,0 +1,105 @@
1
+ export interface GenerationEntry {
2
+ namespace: string;
3
+ label: string;
4
+ model?: string;
5
+ startedAt: number;
6
+ params: Record<string, unknown>;
7
+ /** URL path to the in-progress file. Set by onPartial writes during streaming
8
+ * generation (e.g. accumulated audio written every ~2s). Cleared when
9
+ * generation completes. Flows through the progress SSE to the client. */
10
+ partialSrc?: string;
11
+ }
12
+ type ProgressListener = () => void;
13
+ /** Subscribe to generation progress changes. Returns an unsubscribe function. */
14
+ export declare function onProgressChange(listener: ProgressListener): () => void;
15
+ export interface GenerationProgressSummary {
16
+ counts: Record<string, number>;
17
+ total: number;
18
+ }
19
+ export interface GenerationProgressEntry extends GenerationEntry {
20
+ key: string;
21
+ elapsedMs: number;
22
+ }
23
+ export interface GenerationError {
24
+ key: string;
25
+ namespace: string;
26
+ label: string;
27
+ model?: string;
28
+ error: string;
29
+ durationMs: number;
30
+ }
31
+ export interface GenerationProgressEvent {
32
+ generations: GenerationProgressEntry[];
33
+ errors: GenerationError[];
34
+ summary: GenerationProgressSummary;
35
+ done: boolean;
36
+ }
37
+ /** Get a snapshot of all active generations with elapsed time computed.
38
+ * Drains the error queue so each call returns only new errors since last read. */
39
+ export declare function getGenerationProgress(): GenerationProgressEvent;
40
+ type SerializeResult = {
41
+ bytes: Uint8Array;
42
+ extension: string;
43
+ prefix?: string;
44
+ } | {
45
+ json: unknown;
46
+ extension: '.json';
47
+ prefix?: string;
48
+ };
49
+ export interface CachedGenerateConfig<TParams, TGenerated, TResult> {
50
+ /** Filesystem namespace: files go to `public/generated/{namespace}/` */
51
+ namespace: string;
52
+ /** Human-readable filename prefix derived from params */
53
+ prefixFrom: (params: TParams) => string;
54
+ /** Extract the cache-relevant subset of params. Use this to exclude fields
55
+ * that affect naming but not identity (e.g. `filename` in transcription).
56
+ * Defaults to using all params. Uint8Array values are auto-hashed regardless. */
57
+ cacheKey?: (params: TParams) => Record<string, unknown>;
58
+ /** The actual generation function. Throw on error. */
59
+ generate: (params: TParams) => Promise<TGenerated>;
60
+ /** How to persist the result to disk.
61
+ * Return { bytes, extension } for binary files or { json, extension: '.json' } for data.
62
+ * Optionally return { prefix } to override the filename prefix (e.g. when
63
+ * the readable name comes from the result, not the params). */
64
+ serialize: (result: TGenerated, params: TParams) => SerializeResult;
65
+ /** How to read a cached result back.
66
+ * For binary: receives { urlPath, filePath }, defaults to { src: urlPath }.
67
+ * For JSON: filePath contains the JSON data. */
68
+ deserialize?: (cached: {
69
+ urlPath: string;
70
+ filePath: string;
71
+ }) => TResult;
72
+ /** Model ID key in params, used for progress tracking display. */
73
+ modelFrom?: (params: TParams) => string | undefined;
74
+ /** Called after the main file is written to disk. Use this to write
75
+ * sidecar files (e.g. timestamps JSON alongside audio).
76
+ * Receives the generated result so it can extract extra data to persist. */
77
+ postWrite?: (filePath: string, result: TGenerated, params: TParams) => void;
78
+ }
79
+ /** Result of getCacheInfo — used by server components for sync cache checks
80
+ * and fallback lookup before starting async generation. */
81
+ export interface CacheInfo {
82
+ hash: string;
83
+ prefix: string;
84
+ dir: string;
85
+ key: string;
86
+ cached: string | undefined;
87
+ fallback: {
88
+ filename: string;
89
+ inStale: boolean;
90
+ } | undefined;
91
+ fallbackSrc: string | undefined;
92
+ }
93
+ /** Compute cache info for a given namespace and params without starting generation.
94
+ * Used by server components to check cache and find fallback synchronously. */
95
+ export declare function getCacheInfo(namespace: string, params: Record<string, unknown>, prefixText: string): CacheInfo;
96
+ export type CachedGenerateFn<TParams, TResult> = {
97
+ (params: TParams): Promise<Error | TResult>;
98
+ /** Sync cache check using the same config as the cached function. */
99
+ getCacheInfo(params: TParams): CacheInfo;
100
+ };
101
+ export declare function cachedGenerate<TParams, TGenerated, TResult = {
102
+ src: string;
103
+ }>(config: CachedGenerateConfig<TParams, TGenerated, TResult>): CachedGenerateFn<TParams, TResult>;
104
+ export {};
105
+ //# sourceMappingURL=cached-generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cached-generate.d.ts","sourceRoot":"","sources":["../../src/cli/cached-generate.ts"],"names":[],"mappings":"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"}