@koda-sl/baker-cli 0.39.29 → 0.66.2

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 (315) hide show
  1. package/README.md +1754 -7
  2. package/canvas/avocado-tutorial.json +89 -0
  3. package/canvas/hello-world-composition/index.html +83 -0
  4. package/canvas/hello-world-composition/meta.json +41 -0
  5. package/canvas/hello-world-overlay.json +37 -0
  6. package/canvas/phone-scroll-composition/index.html +141 -0
  7. package/canvas/phone-scroll-composition/meta.json +39 -0
  8. package/canvas/tiktok-captions-composition/index.html +126 -0
  9. package/canvas/tiktok-captions-composition/meta.json +46 -0
  10. package/canvas/video-overlay-composition/index.html +239 -0
  11. package/canvas/video-overlay-composition/meta.json +29 -0
  12. package/dist/cli.js +2 -0
  13. package/dist/cli.js.map +1 -1
  14. package/dist/commands/ads/meta/creatives.js +1 -1
  15. package/dist/commands/canvas/catalog.d.ts +2 -0
  16. package/dist/commands/canvas/catalog.d.ts.map +1 -0
  17. package/dist/commands/canvas/catalog.js +13 -0
  18. package/dist/commands/canvas/catalog.js.map +1 -0
  19. package/dist/commands/canvas/index.d.ts +2 -0
  20. package/dist/commands/canvas/index.d.ts.map +1 -0
  21. package/dist/commands/canvas/index.js +32 -0
  22. package/dist/commands/canvas/index.js.map +1 -0
  23. package/dist/commands/canvas/inspect.d.ts +16 -0
  24. package/dist/commands/canvas/inspect.d.ts.map +1 -0
  25. package/dist/commands/canvas/inspect.js +115 -0
  26. package/dist/commands/canvas/inspect.js.map +1 -0
  27. package/dist/commands/canvas/run.d.ts +24 -0
  28. package/dist/commands/canvas/run.d.ts.map +1 -0
  29. package/dist/commands/canvas/run.js +56 -0
  30. package/dist/commands/canvas/run.js.map +1 -0
  31. package/dist/commands/canvas/scaffold-static-ad.d.ts +40 -0
  32. package/dist/commands/canvas/scaffold-static-ad.d.ts.map +1 -0
  33. package/dist/commands/canvas/scaffold-static-ad.js +265 -0
  34. package/dist/commands/canvas/scaffold-static-ad.js.map +1 -0
  35. package/dist/commands/canvas/scaffold-video.d.ts +44 -0
  36. package/dist/commands/canvas/scaffold-video.d.ts.map +1 -0
  37. package/dist/commands/canvas/scaffold-video.js +235 -0
  38. package/dist/commands/canvas/scaffold-video.js.map +1 -0
  39. package/dist/commands/canvas/validate.d.ts +8 -0
  40. package/dist/commands/canvas/validate.d.ts.map +1 -0
  41. package/dist/commands/canvas/validate.js +37 -0
  42. package/dist/commands/canvas/validate.js.map +1 -0
  43. package/dist/commands/images/find.d.ts +1 -1
  44. package/dist/commands/images/find.d.ts.map +1 -1
  45. package/dist/commands/images/find.js +12 -3
  46. package/dist/commands/images/find.js.map +1 -1
  47. package/dist/commands/images/google.d.ts +1 -1
  48. package/dist/commands/images/google.d.ts.map +1 -1
  49. package/dist/commands/images/google.js +12 -3
  50. package/dist/commands/images/google.js.map +1 -1
  51. package/dist/commands/images/stock.d.ts +1 -1
  52. package/dist/commands/images/stock.d.ts.map +1 -1
  53. package/dist/commands/images/stock.js +7 -3
  54. package/dist/commands/images/stock.js.map +1 -1
  55. package/dist/engine/client/backend-client.d.ts +50 -0
  56. package/dist/engine/client/backend-client.d.ts.map +1 -0
  57. package/dist/engine/client/backend-client.js +20 -0
  58. package/dist/engine/client/backend-client.js.map +1 -0
  59. package/dist/engine/client/env.d.ts +7 -0
  60. package/dist/engine/client/env.d.ts.map +1 -0
  61. package/dist/engine/client/env.js +18 -0
  62. package/dist/engine/client/env.js.map +1 -0
  63. package/dist/engine/client/http.d.ts +56 -0
  64. package/dist/engine/client/http.d.ts.map +1 -0
  65. package/dist/engine/client/http.js +168 -0
  66. package/dist/engine/client/http.js.map +1 -0
  67. package/dist/engine/engine/cache-key.d.ts +19 -0
  68. package/dist/engine/engine/cache-key.d.ts.map +1 -0
  69. package/dist/engine/engine/cache-key.js +33 -0
  70. package/dist/engine/engine/cache-key.js.map +1 -0
  71. package/dist/engine/engine/canonical.d.ts +14 -0
  72. package/dist/engine/engine/canonical.d.ts.map +1 -0
  73. package/dist/engine/engine/canonical.js +53 -0
  74. package/dist/engine/engine/canonical.js.map +1 -0
  75. package/dist/engine/engine/composition-hash.d.ts +14 -0
  76. package/dist/engine/engine/composition-hash.d.ts.map +1 -0
  77. package/dist/engine/engine/composition-hash.js +51 -0
  78. package/dist/engine/engine/composition-hash.js.map +1 -0
  79. package/dist/engine/engine/composition-meta.d.ts +77 -0
  80. package/dist/engine/engine/composition-meta.d.ts.map +1 -0
  81. package/dist/engine/engine/composition-meta.js +199 -0
  82. package/dist/engine/engine/composition-meta.js.map +1 -0
  83. package/dist/engine/engine/context.d.ts +16 -0
  84. package/dist/engine/engine/context.d.ts.map +1 -0
  85. package/dist/engine/engine/context.js +2 -0
  86. package/dist/engine/engine/context.js.map +1 -0
  87. package/dist/engine/engine/define.d.ts +69 -0
  88. package/dist/engine/engine/define.d.ts.map +1 -0
  89. package/dist/engine/engine/define.js +9 -0
  90. package/dist/engine/engine/define.js.map +1 -0
  91. package/dist/engine/engine/didyoumean.d.ts +2 -0
  92. package/dist/engine/engine/didyoumean.d.ts.map +1 -0
  93. package/dist/engine/engine/didyoumean.js +58 -0
  94. package/dist/engine/engine/didyoumean.js.map +1 -0
  95. package/dist/engine/engine/errors.d.ts +41 -0
  96. package/dist/engine/engine/errors.d.ts.map +1 -0
  97. package/dist/engine/engine/errors.js +45 -0
  98. package/dist/engine/engine/errors.js.map +1 -0
  99. package/dist/engine/engine/executor.d.ts +72 -0
  100. package/dist/engine/engine/executor.d.ts.map +1 -0
  101. package/dist/engine/engine/executor.js +445 -0
  102. package/dist/engine/engine/executor.js.map +1 -0
  103. package/dist/engine/engine/refs.d.ts +12 -0
  104. package/dist/engine/engine/refs.d.ts.map +1 -0
  105. package/dist/engine/engine/refs.js +48 -0
  106. package/dist/engine/engine/refs.js.map +1 -0
  107. package/dist/engine/engine/registry.d.ts +11 -0
  108. package/dist/engine/engine/registry.d.ts.map +1 -0
  109. package/dist/engine/engine/registry.js +26 -0
  110. package/dist/engine/engine/registry.js.map +1 -0
  111. package/dist/engine/engine/scheduler.d.ts +10 -0
  112. package/dist/engine/engine/scheduler.d.ts.map +1 -0
  113. package/dist/engine/engine/scheduler.js +89 -0
  114. package/dist/engine/engine/scheduler.js.map +1 -0
  115. package/dist/engine/engine/validator.d.ts +31 -0
  116. package/dist/engine/engine/validator.d.ts.map +1 -0
  117. package/dist/engine/engine/validator.js +501 -0
  118. package/dist/engine/engine/validator.js.map +1 -0
  119. package/dist/engine/index.d.ts +33 -0
  120. package/dist/engine/index.d.ts.map +1 -0
  121. package/dist/engine/index.js +104 -0
  122. package/dist/engine/index.js.map +1 -0
  123. package/dist/engine/lib/ulid.d.ts +3 -0
  124. package/dist/engine/lib/ulid.d.ts.map +1 -0
  125. package/dist/engine/lib/ulid.js +36 -0
  126. package/dist/engine/lib/ulid.js.map +1 -0
  127. package/dist/engine/models/canvas-ad-params.test.d.ts +2 -0
  128. package/dist/engine/models/canvas-ad-params.test.d.ts.map +1 -0
  129. package/dist/engine/models/canvas-ad-params.test.js +60 -0
  130. package/dist/engine/models/canvas-ad-params.test.js.map +1 -0
  131. package/dist/engine/models/registry.d.ts +63 -0
  132. package/dist/engine/models/registry.d.ts.map +1 -0
  133. package/dist/engine/models/registry.js +432 -0
  134. package/dist/engine/models/registry.js.map +1 -0
  135. package/dist/engine/models/validateParams.d.ts +38 -0
  136. package/dist/engine/models/validateParams.d.ts.map +1 -0
  137. package/dist/engine/models/validateParams.js +166 -0
  138. package/dist/engine/models/validateParams.js.map +1 -0
  139. package/dist/engine/nodes/ingest.d.ts +113 -0
  140. package/dist/engine/nodes/ingest.d.ts.map +1 -0
  141. package/dist/engine/nodes/ingest.js +555 -0
  142. package/dist/engine/nodes/ingest.js.map +1 -0
  143. package/dist/engine/nodes/ingest.svg.test.d.ts +2 -0
  144. package/dist/engine/nodes/ingest.svg.test.d.ts.map +1 -0
  145. package/dist/engine/nodes/ingest.svg.test.js +30 -0
  146. package/dist/engine/nodes/ingest.svg.test.js.map +1 -0
  147. package/dist/engine/nodes/local/audioTimeline.d.ts +82 -0
  148. package/dist/engine/nodes/local/audioTimeline.d.ts.map +1 -0
  149. package/dist/engine/nodes/local/audioTimeline.js +97 -0
  150. package/dist/engine/nodes/local/audioTimeline.js.map +1 -0
  151. package/dist/engine/nodes/local/ffmpeg.d.ts +56 -0
  152. package/dist/engine/nodes/local/ffmpeg.d.ts.map +1 -0
  153. package/dist/engine/nodes/local/ffmpeg.js +50 -0
  154. package/dist/engine/nodes/local/ffmpeg.js.map +1 -0
  155. package/dist/engine/nodes/local/fontSpecimen.d.ts +50 -0
  156. package/dist/engine/nodes/local/fontSpecimen.d.ts.map +1 -0
  157. package/dist/engine/nodes/local/fontSpecimen.js +198 -0
  158. package/dist/engine/nodes/local/fontSpecimen.js.map +1 -0
  159. package/dist/engine/nodes/local/hyperframe-snapshot.d.ts +116 -0
  160. package/dist/engine/nodes/local/hyperframe-snapshot.d.ts.map +1 -0
  161. package/dist/engine/nodes/local/hyperframe-snapshot.js +230 -0
  162. package/dist/engine/nodes/local/hyperframe-snapshot.js.map +1 -0
  163. package/dist/engine/nodes/local/hyperframe.d.ts +123 -0
  164. package/dist/engine/nodes/local/hyperframe.d.ts.map +1 -0
  165. package/dist/engine/nodes/local/hyperframe.js +367 -0
  166. package/dist/engine/nodes/local/hyperframe.js.map +1 -0
  167. package/dist/engine/nodes/local/imagemagick.d.ts +56 -0
  168. package/dist/engine/nodes/local/imagemagick.d.ts.map +1 -0
  169. package/dist/engine/nodes/local/imagemagick.js +71 -0
  170. package/dist/engine/nodes/local/imagemagick.js.map +1 -0
  171. package/dist/engine/nodes/local/lib/assets.d.ts +20 -0
  172. package/dist/engine/nodes/local/lib/assets.d.ts.map +1 -0
  173. package/dist/engine/nodes/local/lib/assets.js +40 -0
  174. package/dist/engine/nodes/local/lib/assets.js.map +1 -0
  175. package/dist/engine/nodes/local/lib/cli-runner.d.ts +78 -0
  176. package/dist/engine/nodes/local/lib/cli-runner.d.ts.map +1 -0
  177. package/dist/engine/nodes/local/lib/cli-runner.js +254 -0
  178. package/dist/engine/nodes/local/lib/cli-runner.js.map +1 -0
  179. package/dist/engine/nodes/local/lib/ffmpeg.d.ts +23 -0
  180. package/dist/engine/nodes/local/lib/ffmpeg.d.ts.map +1 -0
  181. package/dist/engine/nodes/local/lib/ffmpeg.js +75 -0
  182. package/dist/engine/nodes/local/lib/ffmpeg.js.map +1 -0
  183. package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts +2 -0
  184. package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts.map +1 -0
  185. package/dist/engine/nodes/local/lib/hyperframe-errors.js +47 -0
  186. package/dist/engine/nodes/local/lib/hyperframe-errors.js.map +1 -0
  187. package/dist/engine/nodes/local/lib/templating.d.ts +22 -0
  188. package/dist/engine/nodes/local/lib/templating.d.ts.map +1 -0
  189. package/dist/engine/nodes/local/lib/templating.js +85 -0
  190. package/dist/engine/nodes/local/lib/templating.js.map +1 -0
  191. package/dist/engine/nodes/local/text.d.ts +6 -0
  192. package/dist/engine/nodes/local/text.d.ts.map +1 -0
  193. package/dist/engine/nodes/local/text.js +15 -0
  194. package/dist/engine/nodes/local/text.js.map +1 -0
  195. package/dist/engine/nodes/remote/delegate.d.ts +25 -0
  196. package/dist/engine/nodes/remote/delegate.d.ts.map +1 -0
  197. package/dist/engine/nodes/remote/delegate.js +160 -0
  198. package/dist/engine/nodes/remote/delegate.js.map +1 -0
  199. package/dist/engine/nodes/remote/dialogue.d.ts +34 -0
  200. package/dist/engine/nodes/remote/dialogue.d.ts.map +1 -0
  201. package/dist/engine/nodes/remote/dialogue.js +54 -0
  202. package/dist/engine/nodes/remote/dialogue.js.map +1 -0
  203. package/dist/engine/nodes/remote/image.d.ts +42 -0
  204. package/dist/engine/nodes/remote/image.d.ts.map +1 -0
  205. package/dist/engine/nodes/remote/image.js +43 -0
  206. package/dist/engine/nodes/remote/image.js.map +1 -0
  207. package/dist/engine/nodes/remote/imageAspectAdapt.d.ts +30 -0
  208. package/dist/engine/nodes/remote/imageAspectAdapt.d.ts.map +1 -0
  209. package/dist/engine/nodes/remote/imageAspectAdapt.js +42 -0
  210. package/dist/engine/nodes/remote/imageAspectAdapt.js.map +1 -0
  211. package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts +39 -0
  212. package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts.map +1 -0
  213. package/dist/engine/nodes/remote/imageBackgroundRemove.js +37 -0
  214. package/dist/engine/nodes/remote/imageBackgroundRemove.js.map +1 -0
  215. package/dist/engine/nodes/remote/imageDescribe.d.ts +29 -0
  216. package/dist/engine/nodes/remote/imageDescribe.d.ts.map +1 -0
  217. package/dist/engine/nodes/remote/imageDescribe.js +25 -0
  218. package/dist/engine/nodes/remote/imageDescribe.js.map +1 -0
  219. package/dist/engine/nodes/remote/imageReferenceSheet.d.ts +34 -0
  220. package/dist/engine/nodes/remote/imageReferenceSheet.d.ts.map +1 -0
  221. package/dist/engine/nodes/remote/imageReferenceSheet.js +38 -0
  222. package/dist/engine/nodes/remote/imageReferenceSheet.js.map +1 -0
  223. package/dist/engine/nodes/remote/imageSearch.d.ts +18 -0
  224. package/dist/engine/nodes/remote/imageSearch.d.ts.map +1 -0
  225. package/dist/engine/nodes/remote/imageSearch.js +22 -0
  226. package/dist/engine/nodes/remote/imageSearch.js.map +1 -0
  227. package/dist/engine/nodes/remote/imageSelect.d.ts +39 -0
  228. package/dist/engine/nodes/remote/imageSelect.d.ts.map +1 -0
  229. package/dist/engine/nodes/remote/imageSelect.js +45 -0
  230. package/dist/engine/nodes/remote/imageSelect.js.map +1 -0
  231. package/dist/engine/nodes/remote/music.d.ts +45 -0
  232. package/dist/engine/nodes/remote/music.d.ts.map +1 -0
  233. package/dist/engine/nodes/remote/music.js +73 -0
  234. package/dist/engine/nodes/remote/music.js.map +1 -0
  235. package/dist/engine/nodes/remote/soundEffect.d.ts +21 -0
  236. package/dist/engine/nodes/remote/soundEffect.d.ts.map +1 -0
  237. package/dist/engine/nodes/remote/soundEffect.js +41 -0
  238. package/dist/engine/nodes/remote/soundEffect.js.map +1 -0
  239. package/dist/engine/nodes/remote/textGenerate.d.ts +21 -0
  240. package/dist/engine/nodes/remote/textGenerate.d.ts.map +1 -0
  241. package/dist/engine/nodes/remote/textGenerate.js +27 -0
  242. package/dist/engine/nodes/remote/textGenerate.js.map +1 -0
  243. package/dist/engine/nodes/remote/tts.d.ts +45 -0
  244. package/dist/engine/nodes/remote/tts.d.ts.map +1 -0
  245. package/dist/engine/nodes/remote/tts.js +66 -0
  246. package/dist/engine/nodes/remote/tts.js.map +1 -0
  247. package/dist/engine/nodes/remote/video.d.ts +58 -0
  248. package/dist/engine/nodes/remote/video.d.ts.map +1 -0
  249. package/dist/engine/nodes/remote/video.js +44 -0
  250. package/dist/engine/nodes/remote/video.js.map +1 -0
  251. package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts +30 -0
  252. package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts.map +1 -0
  253. package/dist/engine/nodes/remote/videoBackgroundRemove.js +29 -0
  254. package/dist/engine/nodes/remote/videoBackgroundRemove.js.map +1 -0
  255. package/dist/engine/nodes/remote/videoDeconstruct.d.ts +61 -0
  256. package/dist/engine/nodes/remote/videoDeconstruct.d.ts.map +1 -0
  257. package/dist/engine/nodes/remote/videoDeconstruct.js +40 -0
  258. package/dist/engine/nodes/remote/videoDeconstruct.js.map +1 -0
  259. package/dist/engine/nodes/remote/videoLipsync.d.ts +37 -0
  260. package/dist/engine/nodes/remote/videoLipsync.d.ts.map +1 -0
  261. package/dist/engine/nodes/remote/videoLipsync.js +26 -0
  262. package/dist/engine/nodes/remote/videoLipsync.js.map +1 -0
  263. package/dist/engine/nodes/remote/videoTranscribe.d.ts +116 -0
  264. package/dist/engine/nodes/remote/videoTranscribe.d.ts.map +1 -0
  265. package/dist/engine/nodes/remote/videoTranscribe.js +123 -0
  266. package/dist/engine/nodes/remote/videoTranscribe.js.map +1 -0
  267. package/dist/engine/nodes/remote/voiceSelect.d.ts +28 -0
  268. package/dist/engine/nodes/remote/voiceSelect.d.ts.map +1 -0
  269. package/dist/engine/nodes/remote/voiceSelect.js +25 -0
  270. package/dist/engine/nodes/remote/voiceSelect.js.map +1 -0
  271. package/dist/engine/scaffold/staticAd.d.ts +44 -0
  272. package/dist/engine/scaffold/staticAd.d.ts.map +1 -0
  273. package/dist/engine/scaffold/staticAd.js +243 -0
  274. package/dist/engine/scaffold/staticAd.js.map +1 -0
  275. package/dist/engine/scaffold/video.d.ts +56 -0
  276. package/dist/engine/scaffold/video.d.ts.map +1 -0
  277. package/dist/engine/scaffold/video.js +709 -0
  278. package/dist/engine/scaffold/video.js.map +1 -0
  279. package/dist/engine/schema/canvas.d.ts +41 -0
  280. package/dist/engine/schema/canvas.d.ts.map +1 -0
  281. package/dist/engine/schema/canvas.js +67 -0
  282. package/dist/engine/schema/canvas.js.map +1 -0
  283. package/dist/engine/schema/catalog.d.ts +25 -0
  284. package/dist/engine/schema/catalog.d.ts.map +1 -0
  285. package/dist/engine/schema/catalog.js +48 -0
  286. package/dist/engine/schema/catalog.js.map +1 -0
  287. package/dist/engine/schema/primitives.d.ts +6 -0
  288. package/dist/engine/schema/primitives.d.ts.map +1 -0
  289. package/dist/engine/schema/primitives.js +4 -0
  290. package/dist/engine/schema/primitives.js.map +1 -0
  291. package/dist/engine/schema/prompts.d.ts +4 -0
  292. package/dist/engine/schema/prompts.d.ts.map +1 -0
  293. package/dist/engine/schema/prompts.js +23 -0
  294. package/dist/engine/schema/prompts.js.map +1 -0
  295. package/dist/engine/schema/refs.d.ts +113 -0
  296. package/dist/engine/schema/refs.d.ts.map +1 -0
  297. package/dist/engine/schema/refs.js +35 -0
  298. package/dist/engine/schema/refs.js.map +1 -0
  299. package/dist/engine/storage/asset-store.d.ts +48 -0
  300. package/dist/engine/storage/asset-store.d.ts.map +1 -0
  301. package/dist/engine/storage/asset-store.js +166 -0
  302. package/dist/engine/storage/asset-store.js.map +1 -0
  303. package/dist/engine/storage/cache-store.d.ts +21 -0
  304. package/dist/engine/storage/cache-store.d.ts.map +1 -0
  305. package/dist/engine/storage/cache-store.js +31 -0
  306. package/dist/engine/storage/cache-store.js.map +1 -0
  307. package/dist/engine/storage/output-writer.d.ts +18 -0
  308. package/dist/engine/storage/output-writer.d.ts.map +1 -0
  309. package/dist/engine/storage/output-writer.js +52 -0
  310. package/dist/engine/storage/output-writer.js.map +1 -0
  311. package/dist/engine/storage/sha256.d.ts +2 -0
  312. package/dist/engine/storage/sha256.d.ts.map +1 -0
  313. package/dist/engine/storage/sha256.js +7 -0
  314. package/dist/engine/storage/sha256.js.map +1 -0
  315. package/package.json +15 -3
@@ -0,0 +1,239 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=1080, height=1920" />
6
+ <script src="./gsap.min.js"></script>
7
+ <style>
8
+ /* Brand font: drop `brand-bold.otf` / `brand-regular.otf` (or .ttf) into
9
+ this composition dir to render overlays in the real brand typeface. If
10
+ the files are absent the @font-face simply fails and the system stack
11
+ below is used — so the composition still renders either way. */
12
+ @font-face {
13
+ font-family: 'BrandFont';
14
+ src: url('./brand-bold.otf') format('opentype'), url('./brand-bold.ttf') format('truetype');
15
+ font-weight: 700 900;
16
+ font-display: swap;
17
+ }
18
+ @font-face {
19
+ font-family: 'BrandFont';
20
+ src: url('./brand-regular.otf') format('opentype'), url('./brand-regular.ttf') format('truetype');
21
+ font-weight: 100 600;
22
+ font-display: swap;
23
+ }
24
+
25
+ * { margin: 0; padding: 0; box-sizing: border-box; }
26
+ html, body { width: 1080px; height: 1920px; overflow: hidden; background: #000; }
27
+ video#bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
28
+
29
+ /* 9-grid: the stage is a 3x3 flex grid; each cell aligns its overlay. */
30
+ #stage { position: absolute; inset: 0; display: grid;
31
+ grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr; padding: 80px 48px; }
32
+ .cell { display: flex; padding: 8px; }
33
+ .cell.top { align-items: flex-start; } .cell.mid { align-items: center; } .cell.bottom { align-items: flex-end; }
34
+ .cell.left { justify-content: flex-start; } .cell.center { justify-content: center; } .cell.right { justify-content: flex-end; }
35
+
36
+ .overlay { visibility: hidden; max-width: 100%; font-family: 'BrandFont', 'Arial Black', 'Helvetica Neue', sans-serif;
37
+ font-weight: 900; line-height: 1.15; text-align: center; word-break: break-word; }
38
+ .overlay.size-small { font-size: 40px; } .overlay.size-medium { font-size: 64px; }
39
+ .overlay.size-large { font-size: 92px; } .overlay.size-huge { font-size: 128px; }
40
+ .overlay .pill { display: inline-block; padding: 0.12em 0.4em; border-radius: 0.22em; }
41
+ /* Per-glyph/word spans for typewriter & karaoke must stay inline. */
42
+ .overlay .tok { display: inline; }
43
+
44
+ .floating { visibility: hidden; font-family: 'Helvetica Neue', sans-serif; font-size: 30px; color: #fff;
45
+ border: 2px dashed rgba(255,255,255,0.85); border-radius: 12px; padding: 10px 16px;
46
+ background: rgba(0,0,0,0.45); max-width: 90%; text-align: center; }
47
+ .floating .kind { display: block; font-size: 20px; opacity: 0.7; text-transform: uppercase; letter-spacing: 1px; }
48
+ </style>
49
+ </head>
50
+ <body>
51
+ <div id="root" data-composition-id="main" data-start="0" data-duration="{{duration}}" data-width="1080" data-height="1920">
52
+ <video id="bg" src="background.mp4" muted></video>
53
+ <div id="stage"></div>
54
+ </div>
55
+
56
+ <script>
57
+ (() => {
58
+ const OVERLAYS = {{overlays}};
59
+ const FLOATING = {{floating_elements}};
60
+ const DURATION = parseFloat('{{duration}}');
61
+ const stage = document.getElementById('stage');
62
+ const tl = gsap.timeline({ paused: true });
63
+
64
+ const ROWS = { top: 'top', mid: 'mid', center: 'mid', bottom: 'bottom' };
65
+ const COLS = { left: 'left', center: 'center', right: 'right' };
66
+ // 3x3 cells indexed by "row_col"; build them once.
67
+ const cells = {};
68
+ for (const r of ['top', 'mid', 'bottom']) {
69
+ for (const c of ['left', 'center', 'right']) {
70
+ const el = document.createElement('div');
71
+ el.className = `cell ${r} ${c}`;
72
+ stage.appendChild(el);
73
+ cells[`${r}_${c}`] = el;
74
+ }
75
+ }
76
+ function cellFor(position) {
77
+ // position like "bottom_center" / "mid_left" / "center" (legacy mid_center alias)
78
+ const p = String(position || 'bottom_center');
79
+ if (p === 'center') return cells.mid_center;
80
+ const [rawRow, rawCol] = p.split('_');
81
+ const row = ROWS[rawRow] || 'bottom';
82
+ const col = COLS[rawCol] || 'center';
83
+ return cells[`${row}_${col}`];
84
+ }
85
+
86
+ function applyTextStyle(el, style) {
87
+ const s = style || {};
88
+ el.classList.add('size-' + (s.size || 'medium'));
89
+ if (s.color_hex) el.style.color = s.color_hex; else el.style.color = '#fff';
90
+ if (s.casing === 'upper') el.style.textTransform = 'uppercase';
91
+ else if (s.casing === 'lower') el.style.textTransform = 'lowercase';
92
+ else if (s.casing === 'title') el.style.textTransform = 'capitalize';
93
+ // Background heuristic from a free-text descriptor like "white rounded rectangle".
94
+ const bg = (s.background || '').toLowerCase();
95
+ const span = document.createElement('span');
96
+ span.textContent = '';
97
+ if (bg && bg !== 'none' && bg !== 'transparent') {
98
+ span.className = 'pill';
99
+ if (bg.includes('white')) { span.style.background = '#fff'; if (!s.color_hex) el.style.color = '#111'; }
100
+ else if (bg.includes('black')) { span.style.background = 'rgba(0,0,0,0.85)'; }
101
+ else { span.style.background = 'rgba(0,0,0,0.6)'; }
102
+ }
103
+ // Stroke/shadow: default a strong outline for legibility unless a pill bg is used.
104
+ if (!span.className) {
105
+ el.style.textShadow = s.stroke_or_shadow
106
+ ? '2px 2px 0 rgba(0,0,0,0.9), -2px -2px 0 rgba(0,0,0,0.9), 2px -2px 0 rgba(0,0,0,0.9), -2px 2px 0 rgba(0,0,0,0.9)'
107
+ : '0 3px 10px rgba(0,0,0,0.6)';
108
+ }
109
+ return span;
110
+ }
111
+
112
+ // Read the free-text `animation_detail` for speed / easing / distance hints
113
+ // so two overlays with the same coarse `animation` can still differ.
114
+ function tuneFromDetail(detail) {
115
+ const d = String(detail || '').toLowerCase();
116
+ let durMul = 1, ease = null, dist = 1;
117
+ if (/(fast|quick|snappy|rapid|instant|sharp)/.test(d)) durMul = 0.6;
118
+ if (/(slow|gentle|smooth|gradual|soft|ease)/.test(d)) durMul = 1.5;
119
+ if (/(bounce|spring|elastic|jelly)/.test(d)) ease = 'elastic.out(1,0.5)';
120
+ if (/(overshoot|back|punch)/.test(d)) ease = 'back.out(1.7)';
121
+ if (/(big|large|dramatic|hard|strong)/.test(d)) dist = 1.6;
122
+ return { durMul, ease, dist };
123
+ }
124
+
125
+ function animateIn(el, animation, at, detail) {
126
+ const a = String(animation || 'fade');
127
+ const t = tuneFromDetail(detail);
128
+ const base = 0.25 * t.durMul;
129
+ if (a === 'pop' || a === 'bounce') {
130
+ tl.fromTo(el, { scale: 0.6, opacity: 0 }, { scale: 1, opacity: 1, duration: base, ease: t.ease || (a === 'bounce' ? 'elastic.out(1,0.5)' : 'back.out(1.7)') }, at);
131
+ } else if (a === 'slide_up') {
132
+ tl.fromTo(el, { y: 60 * t.dist, opacity: 0 }, { y: 0, opacity: 1, duration: base, ease: t.ease || 'power2.out' }, at);
133
+ } else if (a === 'slide_down') {
134
+ tl.fromTo(el, { y: -60 * t.dist, opacity: 0 }, { y: 0, opacity: 1, duration: base, ease: t.ease || 'power2.out' }, at);
135
+ } else if (a === 'shake') {
136
+ tl.fromTo(el, { opacity: 0 }, { opacity: 1, duration: 0.1 }, at);
137
+ tl.to(el, { x: '+=' + (12 * t.dist), duration: 0.05, repeat: 5, yoyo: true }, at);
138
+ } else if (a === 'none' || a === 'other') {
139
+ tl.set(el, { opacity: 1 }, at);
140
+ } else {
141
+ // fade
142
+ tl.fromTo(el, { opacity: 0 }, { opacity: 1, duration: 0.2 * t.durMul, ease: 'power1.out' }, at);
143
+ }
144
+ }
145
+
146
+ // Build the visible content. For typewriter/karaoke we split the text into
147
+ // per-glyph / per-word tokens so the reveal can be driven across the
148
+ // overlay's own on-screen duration (independent of the voiceover track).
149
+ function buildContent(container, ov) {
150
+ const a = String(ov.animation || 'fade');
151
+ const text = String(ov.text == null ? '' : ov.text);
152
+ if (a === 'typewriter') {
153
+ const spans = [];
154
+ for (const ch of Array.from(text)) {
155
+ const s = document.createElement('span');
156
+ s.className = 'tok';
157
+ s.textContent = ch;
158
+ s.style.opacity = '0';
159
+ container.appendChild(s);
160
+ if (ch.trim() !== '') spans.push(s);
161
+ else s.style.opacity = '1';
162
+ }
163
+ return { mode: 'typewriter', spans };
164
+ }
165
+ if (a === 'karaoke') {
166
+ const spans = [];
167
+ for (const part of text.split(/(\s+)/)) {
168
+ if (part === '') continue;
169
+ if (/^\s+$/.test(part)) { container.appendChild(document.createTextNode(part)); continue; }
170
+ const s = document.createElement('span');
171
+ s.className = 'tok';
172
+ s.textContent = part;
173
+ s.style.opacity = '0.4';
174
+ container.appendChild(s);
175
+ spans.push(s);
176
+ }
177
+ return { mode: 'karaoke', spans };
178
+ }
179
+ container.textContent = text;
180
+ return { mode: 'plain', spans: [] };
181
+ }
182
+
183
+ (OVERLAYS || []).forEach((ov, i) => {
184
+ if (!ov || !ov.text) return;
185
+ const el = document.createElement('div');
186
+ el.className = 'overlay';
187
+ el.id = 'ov_' + i;
188
+ const span = applyTextStyle(el, ov.style);
189
+ const content = buildContent(span, ov);
190
+ el.appendChild(span);
191
+ cellFor(ov.position).appendChild(el);
192
+
193
+ const at = typeof ov.appears_at_s === 'number' ? ov.appears_at_s : 0;
194
+ const dur = typeof ov.duration_s === 'number' ? ov.duration_s : 2.5;
195
+ tl.set(el, { visibility: 'visible' }, at);
196
+
197
+ if (content.mode === 'typewriter' && content.spans.length) {
198
+ // Type the glyphs across the first ~70% of the overlay's life.
199
+ const reveal = Math.min(Math.max(dur * 0.7, 0.3), 1.8);
200
+ tl.set(el, { opacity: 1 }, at);
201
+ tl.to(content.spans, { opacity: 1, duration: 0.01, ease: 'none', stagger: reveal / content.spans.length }, at);
202
+ } else if (content.mode === 'karaoke' && content.spans.length) {
203
+ // Light up each word in sequence across the overlay's duration.
204
+ const reveal = Math.min(Math.max(dur * 0.85, 0.4), Math.max(dur - 0.2, 0.4));
205
+ tl.set(el, { opacity: 1 }, at);
206
+ tl.to(content.spans, { opacity: 1, duration: 0.12, ease: 'power1.out', stagger: reveal / content.spans.length }, at);
207
+ } else {
208
+ animateIn(el, ov.animation, at, ov.animation_detail);
209
+ }
210
+
211
+ tl.to(el, { opacity: 0, duration: 0.2 }, Math.max(at + 0.2, at + dur));
212
+ tl.set(el, { visibility: 'hidden' }, at + dur + 0.21);
213
+ });
214
+
215
+ (FLOATING || []).forEach((fe, i) => {
216
+ if (!fe) return;
217
+ const el = document.createElement('div');
218
+ el.className = 'floating';
219
+ el.id = 'fe_' + i;
220
+ el.innerHTML = '<span class="kind">' + (fe.kind || 'element') + '</span>';
221
+ el.appendChild(document.createTextNode(fe.description || ''));
222
+ cellFor(fe.position).appendChild(el);
223
+
224
+ const at = typeof fe.appears_at_s === 'number' ? fe.appears_at_s : 0;
225
+ const dur = typeof fe.duration_s === 'number' ? fe.duration_s : 2.5;
226
+ tl.set(el, { visibility: 'visible' }, at);
227
+ tl.fromTo(el, { opacity: 0 }, { opacity: 1, duration: 0.2 }, at);
228
+ tl.to(el, { opacity: 0, duration: 0.2 }, at + dur);
229
+ tl.set(el, { visibility: 'hidden' }, at + dur + 0.21);
230
+ });
231
+
232
+ // Keep the timeline alive to the full video duration.
233
+ tl.to({}, { duration: 0.01 }, Math.max(0.01, DURATION - 0.01));
234
+ window.__timelines = window.__timelines || {};
235
+ window.__timelines.main = tl;
236
+ })();
237
+ </script>
238
+ </body>
239
+ </html>
@@ -0,0 +1,29 @@
1
+ {
2
+ "id": "video-overlay",
3
+ "title": "Burn timed text overlays + floating-element placeholders over a video",
4
+ "description": "Generic overlay renderer for video reproduction. Takes the `overlays` (and optional `floating_elements`) arrays straight from a video_deconstruct blueprint and renders each one over a background video at its absolute timestamp, 9-grid position, animation, and typographic style. Honors fade/pop/bounce/slide_up/slide_down/shake plus glyph-by-glyph `typewriter` and word-by-word `karaoke` reveals, and tunes easing/speed from each overlay's free-text `animation_detail`. For on-brand type, drop `brand-bold.otf`/`brand-regular.otf` (or .ttf) into this dir — they are wired via @font-face and fall back to a system stack when absent. Fixed 1080x1920 (vertical); copy + edit width/height for other aspect ratios.",
5
+ "width": 1080,
6
+ "height": 1920,
7
+ "fps": 30,
8
+ "default_duration": 8,
9
+ "inputs": {
10
+ "background": {
11
+ "kind": "video",
12
+ "required": true,
13
+ "staged_as": "background.mp4",
14
+ "description": "The base video to burn overlays onto (e.g. the concatenated reproduction clips)."
15
+ }
16
+ },
17
+ "params": {
18
+ "overlays": {
19
+ "kind": "json",
20
+ "required": true,
21
+ "description": "Array of overlay objects from the blueprint: {text, appears_at_s, duration_s, position(9-grid: top_left..bottom_center), animation(none|fade|pop|slide_up|slide_down|typewriter|bounce|karaoke|shake|other), style{font_style, casing, color_hex, background, stroke_or_shadow, size(small|medium|large|huge)}}."
22
+ },
23
+ "floating_elements": {
24
+ "kind": "json",
25
+ "default": [],
26
+ "description": "Array of non-text floating elements: {kind, description, appears_at_s, duration_s, position}. Rendered as labeled dashed placeholders for the agent to replace with real image overlays."
27
+ }
28
+ }
29
+ }
package/dist/cli.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { defineCommand, runMain } from "citty";
3
3
  import { actionsCommand } from "./commands/actions/index.js";
4
4
  import { adsCommand } from "./commands/ads/index.js";
5
+ import { canvasCommand } from "./commands/canvas/index.js";
5
6
  import { ga4Command } from "./commands/ga4/index.js";
6
7
  import { gscCommand } from "./commands/gsc/index.js";
7
8
  import { imagesCommand } from "./commands/images/index.js";
@@ -33,6 +34,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`,
33
34
  images: imagesCommand,
34
35
  videos: videosCommand,
35
36
  testimonials: testimonialsCommand,
37
+ canvas: canvasCommand,
36
38
  schema: schemaCommand,
37
39
  },
38
40
  });
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,IAAI,GAAG,aAAa,CAAC;IACzB,IAAI,EAAE;QACJ,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,aAAa,EAAE;QACxB,WAAW,EAAE;;;;;;yEAMwD;KACtE;IACD,WAAW,EAAE;QACX,OAAO,EAAE,cAAc;QACvB,mBAAmB,EAAE,uBAAuB;QAC5C,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,eAAe;QACzB,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,aAAa;QACrB,YAAY,EAAE,mBAAmB;QACjC,MAAM,EAAE,aAAa;KACtB;CACF,CAAC,CAAC;AAEH,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,IAAI,GAAG,aAAa,CAAC;IACzB,IAAI,EAAE;QACJ,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,aAAa,EAAE;QACxB,WAAW,EAAE;;;;;;yEAMwD;KACtE;IACD,WAAW,EAAE;QACX,OAAO,EAAE,cAAc;QACvB,mBAAmB,EAAE,uBAAuB;QAC5C,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,UAAU;QACf,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,eAAe;QACzB,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,aAAa;QACrB,YAAY,EAAE,mBAAmB;QACjC,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,aAAa;KACtB;CACF,CAAC,CAAC;AAEH,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -8,7 +8,7 @@ export const creativesCommand = defineCommand({
8
8
  description: `List ad creatives in an account, or fetch a single creative by ID.
9
9
 
10
10
  Important: Meta creatives are effectively immutable once attached to an ad. Editing copy/image/CTA = create
11
- a new creative + reattach. Bake this into any agentic edit workflow.
11
+ a new creative + reattach. Bake this into any agentic edit canvas.
12
12
 
13
13
  Examples:
14
14
  baker ads meta creatives --account-id act_123
@@ -0,0 +1,2 @@
1
+ export declare const catalogCommand: import("citty").CommandDef<import("citty").ArgsDef>;
2
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/commands/canvas/catalog.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,qDAUzB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { defineCommand } from "citty";
2
+ import { defaultRegistry, generateCatalog } from "../../engine/index.js";
3
+ export const catalogCommand = defineCommand({
4
+ meta: {
5
+ name: "catalog",
6
+ description: "Print the agent-facing node catalog (JSON Schema). Includes every registered node grouped by category.",
7
+ },
8
+ async run() {
9
+ const cat = await generateCatalog(defaultRegistry());
10
+ process.stdout.write(`${JSON.stringify(cat, null, 2)}\n`);
11
+ },
12
+ });
13
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../src/commands/canvas/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;IAC1C,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,WAAW,EACT,wGAAwG;KAC3G;IACD,KAAK,CAAC,GAAG;QACP,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,eAAe,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const canvasCommand: import("citty").CommandDef<import("citty").ArgsDef>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/canvas/index.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,aAAa,qDAuBxB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { defineCommand } from "citty";
2
+ import { catalogCommand } from "./catalog.js";
3
+ import { inspectCommand } from "./inspect.js";
4
+ import { runCommand } from "./run.js";
5
+ import { scaffoldStaticAdCommand } from "./scaffold-static-ad.js";
6
+ import { scaffoldVideoCommand } from "./scaffold-video.js";
7
+ import { validateCommand } from "./validate.js";
8
+ export const canvasCommand = defineCommand({
9
+ meta: {
10
+ name: "canvas",
11
+ description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
12
+
13
+ Auth: BAKER_API_KEY (must start with bk_) + BAKER_API_URL (your Convex .convex.site URL).
14
+
15
+ Subcommands:
16
+ baker canvas validate <file.json> — schema/registry check + composition-meta deep check + cost preview
17
+ baker canvas run <file.json> — execute the canvas, write outputs to ./canvas/<run_id>/
18
+ baker canvas catalog — print the agent-facing node + composition catalog (JSON Schema)
19
+ baker canvas inspect <run_id> — one-page summary of a completed run
20
+ baker canvas scaffold-video <video> — turn a reference video into a runnable reproduction canvas (deconstruct + recurring-element detection)
21
+ baker canvas scaffold-static-ad <image> — turn a source image into a runnable static-ad canvas (describe + element detection)`,
22
+ },
23
+ subCommands: {
24
+ run: runCommand,
25
+ validate: validateCommand,
26
+ catalog: catalogCommand,
27
+ inspect: inspectCommand,
28
+ "scaffold-video": scaffoldVideoCommand,
29
+ "scaffold-static-ad": scaffoldStaticAdCommand,
30
+ },
31
+ });
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/canvas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE;;;;;;;;;;2IAU0H;KACxI;IACD,WAAW,EAAE;QACX,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,cAAc;QACvB,OAAO,EAAE,cAAc;QACvB,gBAAgB,EAAE,oBAAoB;QACtC,oBAAoB,EAAE,uBAAuB;KAC9C;CACF,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ export declare const inspectCommand: import("citty").CommandDef<{
2
+ readonly run: {
3
+ readonly type: "positional";
4
+ readonly required: true;
5
+ readonly description: "Run id (e.g. r_01K...) or absolute run directory";
6
+ };
7
+ readonly "outputs-dir": {
8
+ readonly type: "string";
9
+ readonly description: "Per-run outputs root (default ./canvas)";
10
+ };
11
+ readonly thumbnails: {
12
+ readonly type: "boolean";
13
+ readonly description: "Extract start/middle/end frames from every video output (requires ffmpeg)";
14
+ };
15
+ }>;
16
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../../src/commands/canvas/inspect.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;EAwCzB,CAAC"}
@@ -0,0 +1,115 @@
1
+ import { execFile } from "node:child_process";
2
+ import { readdir, readFile, stat } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { defineCommand } from "citty";
6
+ const execFileAsync = promisify(execFile);
7
+ export const inspectCommand = defineCommand({
8
+ meta: {
9
+ name: "inspect",
10
+ description: "Dump a one-page summary of a canvas run: per-node duration + cache status, list of output files in the run dir, and optionally three thumbnail frames per video output. Pass either a run_id (resolved against --outputs-dir) or an absolute run directory.",
11
+ },
12
+ args: {
13
+ run: { type: "positional", required: true, description: "Run id (e.g. r_01K...) or absolute run directory" },
14
+ "outputs-dir": { type: "string", description: "Per-run outputs root (default ./canvas)" },
15
+ thumbnails: {
16
+ type: "boolean",
17
+ description: "Extract start/middle/end frames from every video output (requires ffmpeg)",
18
+ },
19
+ },
20
+ async run({ args }) {
21
+ const outputsDir = path.resolve(String(args["outputs-dir"] ?? "canvas"));
22
+ const runArg = String(args.run);
23
+ const runDir = await resolveRunDir(runArg, outputsDir);
24
+ const manifest = await loadManifest(runDir);
25
+ const files = await listRunFiles(runDir);
26
+ const videos = files.filter((f) => isVideoFile(f.path));
27
+ let thumbnails = [];
28
+ if (args.thumbnails) {
29
+ thumbnails = await extractThumbnails(videos.map((v) => v.path));
30
+ }
31
+ const summary = {
32
+ ok: true,
33
+ run_id: manifest.run_id ?? path.basename(runDir),
34
+ run_dir: runDir,
35
+ stats: manifest.stats ?? null,
36
+ output: manifest.output ?? null,
37
+ node_runs: manifest.node_runs ?? [],
38
+ files: files.map((f) => ({ name: f.name, path: f.path, size_bytes: f.size })),
39
+ thumbnails,
40
+ };
41
+ process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`);
42
+ },
43
+ });
44
+ async function resolveRunDir(run, outputsDir) {
45
+ if (path.isAbsolute(run)) {
46
+ const s = await stat(run).catch(() => null);
47
+ if (s?.isDirectory())
48
+ return run;
49
+ throw new Error(`inspect: ${run} is not a directory`);
50
+ }
51
+ const candidate = path.join(outputsDir, run);
52
+ const s = await stat(candidate).catch(() => null);
53
+ if (s?.isDirectory())
54
+ return candidate;
55
+ throw new Error(`inspect: no run directory at ${candidate}`);
56
+ }
57
+ async function loadManifest(runDir) {
58
+ const manifestPath = path.join(runDir, "manifest.json");
59
+ try {
60
+ const raw = await readFile(manifestPath, "utf-8");
61
+ return JSON.parse(raw);
62
+ }
63
+ catch {
64
+ return {};
65
+ }
66
+ }
67
+ async function listRunFiles(runDir) {
68
+ const out = [];
69
+ const names = await readdir(runDir);
70
+ for (const name of names) {
71
+ const abs = path.join(runDir, name);
72
+ const s = await stat(abs).catch(() => null);
73
+ if (!s?.isFile())
74
+ continue;
75
+ out.push({ name, path: abs, size: s.size });
76
+ }
77
+ out.sort((a, b) => a.name.localeCompare(b.name));
78
+ return out;
79
+ }
80
+ function isVideoFile(p) {
81
+ return /\.(mp4|webm|mov)$/i.test(p);
82
+ }
83
+ async function extractThumbnails(videoPaths) {
84
+ const out = [];
85
+ for (const v of videoPaths) {
86
+ const duration = await probeDuration(v).catch(() => null);
87
+ if (duration === null) {
88
+ out.push({ video: v, frames: [] });
89
+ continue;
90
+ }
91
+ const frames = [];
92
+ const checkpoints = [0.05, 0.5, 0.95];
93
+ const base = v.replace(/\.[^.]+$/, "");
94
+ for (const ratio of checkpoints) {
95
+ const at = Math.max(0, Math.min(duration * ratio, duration - 0.01));
96
+ const dest = `${base}__frame_${Math.round(ratio * 100)
97
+ .toString()
98
+ .padStart(2, "0")}.png`;
99
+ try {
100
+ await execFileAsync("ffmpeg", ["-ss", at.toFixed(3), "-i", v, "-frames:v", "1", "-y", dest]);
101
+ frames.push(dest);
102
+ }
103
+ catch {
104
+ // skip — best-effort; thumbnail extraction is non-fatal.
105
+ }
106
+ }
107
+ out.push({ video: v, frames });
108
+ }
109
+ return out;
110
+ }
111
+ async function probeDuration(filePath) {
112
+ const { stdout } = await execFileAsync("ffprobe", ["-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", filePath], { encoding: "utf-8" });
113
+ return Number.parseFloat(stdout.trim());
114
+ }
115
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../../src/commands/canvas/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export declare const runCommand: import("citty").CommandDef<{
2
+ readonly file: {
3
+ readonly type: "positional";
4
+ readonly required: true;
5
+ readonly description: "Path to canvas JSON";
6
+ };
7
+ readonly "cache-dir": {
8
+ readonly type: "string";
9
+ readonly description: "Cache root (default ./canvas/.cache)";
10
+ };
11
+ readonly "outputs-dir": {
12
+ readonly type: "string";
13
+ readonly description: "Per-run outputs root (default ./canvas)";
14
+ };
15
+ readonly "run-id": {
16
+ readonly type: "string";
17
+ readonly description: "Override run id";
18
+ };
19
+ readonly "cache-policy": {
20
+ readonly type: "string";
21
+ readonly description: "read_write | bypass | read_only";
22
+ };
23
+ }>;
24
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/canvas/run.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;EAwDrB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { defineCommand } from "citty";
4
+ import { createEngineFromEnv, ValidationError } from "../../engine/index.js";
5
+ export const runCommand = defineCommand({
6
+ meta: { name: "run", description: "Validate and execute a canvas JSON file." },
7
+ args: {
8
+ file: { type: "positional", required: true, description: "Path to canvas JSON" },
9
+ "cache-dir": { type: "string", description: "Cache root (default ./canvas/.cache)" },
10
+ "outputs-dir": { type: "string", description: "Per-run outputs root (default ./canvas)" },
11
+ "run-id": { type: "string", description: "Override run id" },
12
+ "cache-policy": { type: "string", description: "read_write | bypass | read_only" },
13
+ },
14
+ async run({ args }) {
15
+ const filePath = path.resolve(String(args.file));
16
+ const raw = await readFile(filePath, "utf8");
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(raw);
20
+ }
21
+ catch (e) {
22
+ const msg = e instanceof Error ? e.message : String(e);
23
+ process.stderr.write(`[error] ${filePath}: JSON parse error: ${msg}\n`);
24
+ process.exit(2);
25
+ }
26
+ const engine = createEngineFromEnv({
27
+ cacheDir: args["cache-dir"] ? String(args["cache-dir"]) : undefined,
28
+ outputsDir: args["outputs-dir"] ? String(args["outputs-dir"]) : undefined,
29
+ log: (line) => process.stdout.write(`${line}\n`),
30
+ });
31
+ try {
32
+ const policy = (args["cache-policy"] ?? "read_write");
33
+ const result = await engine.run(parsed, {
34
+ run_id: args["run-id"] ? String(args["run-id"]) : undefined,
35
+ cache_policy: policy,
36
+ });
37
+ process.stdout.write(`${JSON.stringify({
38
+ ok: true,
39
+ run_id: result.run_id,
40
+ outputs_dir: result.outputs_dir,
41
+ output: result.output,
42
+ stats: result.stats,
43
+ }, null, 2)}\n`);
44
+ }
45
+ catch (e) {
46
+ if (e instanceof ValidationError) {
47
+ process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: e.issues } }, null, 2)}\n`);
48
+ process.exit(2);
49
+ }
50
+ const msg = e instanceof Error ? e.message : String(e);
51
+ process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "runtime", message: msg } }, null, 2)}\n`);
52
+ process.exit(1);
53
+ }
54
+ },
55
+ });
56
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/canvas/run.ts"],"names":[],"mappings":"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"}