@crievo/omni 0.0.0-stage → 0.1.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 (708) hide show
  1. package/.env.example +41 -0
  2. package/README.md +2 -2
  3. package/bin/omni.mjs +18 -0
  4. package/docs/onboarding/clone-voice.png +0 -0
  5. package/docs/onboarding/getting-started.png +0 -0
  6. package/docs/onboarding/new-video.png +0 -0
  7. package/docs/onboarding/providers.png +0 -0
  8. package/docs/onboarding/publish.png +0 -0
  9. package/docs/onboarding/references.png +0 -0
  10. package/docs/onboarding.md +212 -0
  11. package/omnivideo.config.example.json +437 -0
  12. package/package.json +40 -4
  13. package/reference/captions.md +156 -0
  14. package/reference/carousel-contract.md +91 -0
  15. package/reference/cloud.md +96 -0
  16. package/reference/learnings.md +792 -0
  17. package/reference/omnichat.md +305 -0
  18. package/reference/premiere-mcp.md +91 -0
  19. package/reference/publish.md +305 -0
  20. package/reference/scenes-contract.md +109 -0
  21. package/reference/studio.md +666 -0
  22. package/reference/voicestudio.md +81 -0
  23. package/reference/writing-for-voice.md +67 -0
  24. package/requirements.txt +3 -0
  25. package/studio/api/app.ts +87 -0
  26. package/studio/api/lib/errors.ts +33 -0
  27. package/studio/api/lib/files.ts +41 -0
  28. package/studio/api/lib/hono.ts +9 -0
  29. package/studio/api/lib/result.ts +14 -0
  30. package/studio/api/lib/validate.ts +31 -0
  31. package/studio/api/lib/video.ts +10 -0
  32. package/studio/api/middleware/json-charset.ts +11 -0
  33. package/studio/api/middleware/local-only.ts +32 -0
  34. package/studio/api/middleware/no-timeout.ts +10 -0
  35. package/studio/api/routes/admin.ts +18 -0
  36. package/studio/api/routes/agent-cascade.ts +100 -0
  37. package/studio/api/routes/agent-history.ts +23 -0
  38. package/studio/api/routes/agent.ts +162 -0
  39. package/studio/api/routes/analytics.ts +31 -0
  40. package/studio/api/routes/approval.ts +60 -0
  41. package/studio/api/routes/archive.ts +12 -0
  42. package/studio/api/routes/captions.ts +28 -0
  43. package/studio/api/routes/carousel.ts +38 -0
  44. package/studio/api/routes/clone.ts +27 -0
  45. package/studio/api/routes/create.ts +19 -0
  46. package/studio/api/routes/events.ts +11 -0
  47. package/studio/api/routes/export.ts +14 -0
  48. package/studio/api/routes/media.ts +30 -0
  49. package/studio/api/routes/omnichat.ts +113 -0
  50. package/studio/api/routes/onboarding.ts +14 -0
  51. package/studio/api/routes/publish.ts +40 -0
  52. package/studio/api/routes/queue.ts +14 -0
  53. package/studio/api/routes/references.ts +40 -0
  54. package/studio/api/routes/runner.ts +17 -0
  55. package/studio/api/routes/schedule.ts +47 -0
  56. package/studio/api/routes/services.ts +11 -0
  57. package/studio/api/routes/sessions.ts +27 -0
  58. package/studio/api/routes/settings.ts +102 -0
  59. package/studio/api/routes/sound.ts +45 -0
  60. package/studio/api/routes/thumbnail.ts +18 -0
  61. package/studio/api/routes/usage.ts +13 -0
  62. package/studio/api/routes/videos.ts +41 -0
  63. package/studio/api/routes/voices.ts +71 -0
  64. package/studio/api/services/admin.ts +113 -0
  65. package/studio/api/services/agent-cascade.ts +975 -0
  66. package/studio/api/services/agent-claude.ts +47 -0
  67. package/studio/api/services/agent-history.ts +103 -0
  68. package/studio/api/services/agent-persona.ts +77 -0
  69. package/studio/api/services/agent-tools.ts +2237 -0
  70. package/studio/api/services/agent-ui-tools.ts +259 -0
  71. package/studio/api/services/agent-wait.ts +32 -0
  72. package/studio/api/services/agent.ts +553 -0
  73. package/studio/api/services/analytics.ts +92 -0
  74. package/studio/api/services/approval.ts +134 -0
  75. package/studio/api/services/archive.ts +38 -0
  76. package/studio/api/services/captions.ts +268 -0
  77. package/studio/api/services/carousel.ts +206 -0
  78. package/studio/api/services/classify.ts +196 -0
  79. package/studio/api/services/clone-phrases.ts +75 -0
  80. package/studio/api/services/clone.ts +722 -0
  81. package/studio/api/services/create.ts +421 -0
  82. package/studio/api/services/events.ts +215 -0
  83. package/studio/api/services/media.ts +32 -0
  84. package/studio/api/services/omnichat.ts +624 -0
  85. package/studio/api/services/onboarding.ts +77 -0
  86. package/studio/api/services/publish.ts +287 -0
  87. package/studio/api/services/queue.ts +150 -0
  88. package/studio/api/services/references.ts +269 -0
  89. package/studio/api/services/root.ts +60 -0
  90. package/studio/api/services/services.ts +114 -0
  91. package/studio/api/services/sessions.ts +1007 -0
  92. package/studio/api/services/settings.ts +983 -0
  93. package/studio/api/services/sound.ts +311 -0
  94. package/studio/api/services/thumbnail.ts +133 -0
  95. package/studio/api/services/usage.ts +27 -0
  96. package/studio/api/services/videos.ts +418 -0
  97. package/studio/api/services/voice-pause.ts +98 -0
  98. package/studio/api/services/voices.ts +324 -0
  99. package/studio/runner/runner.ts +244 -0
  100. package/studio/shared/omni-actions.ts +68 -0
  101. package/studio/shared/omni-admin.ts +52 -0
  102. package/studio/shared/omni-farewell.ts +48 -0
  103. package/studio/shared/omni-hotword.ts +20 -0
  104. package/studio/shared/omni-screens.ts +228 -0
  105. package/studio/shared/schemas/admin.ts +15 -0
  106. package/studio/shared/schemas/agent-cascade.ts +58 -0
  107. package/studio/shared/schemas/agent-history.ts +73 -0
  108. package/studio/shared/schemas/agent.ts +50 -0
  109. package/studio/shared/schemas/analytics.ts +6 -0
  110. package/studio/shared/schemas/approval.ts +22 -0
  111. package/studio/shared/schemas/captions.ts +19 -0
  112. package/studio/shared/schemas/carousel.ts +26 -0
  113. package/studio/shared/schemas/clone.ts +40 -0
  114. package/studio/shared/schemas/common.ts +16 -0
  115. package/studio/shared/schemas/omnichat.ts +54 -0
  116. package/studio/shared/schemas/onboarding.ts +5 -0
  117. package/studio/shared/schemas/publish.ts +45 -0
  118. package/studio/shared/schemas/references.ts +20 -0
  119. package/studio/shared/schemas/settings.ts +82 -0
  120. package/studio/shared/schemas/sound.ts +22 -0
  121. package/studio/shared/schemas/videos.ts +38 -0
  122. package/studio/shared/schemas/voices.ts +23 -0
  123. package/studio/shared/types/api.ts +1290 -0
  124. package/studio/studio.ts +148 -0
  125. package/studio/tsconfig.json +15 -0
  126. package/studio/web/assets/logos/cartesia.svg +4 -0
  127. package/studio/web/assets/logos/elevenlabs.svg +12 -0
  128. package/studio/web/assets/logos/fish.svg +24 -0
  129. package/studio/web/assets/logos/omni-black.png +0 -0
  130. package/studio/web/assets/logos/omni-white.png +0 -0
  131. package/studio/web/assets/logos/voicestudio.svg +21 -0
  132. package/studio/web/components/AgentMark.tsx +7 -0
  133. package/studio/web/components/AgentWalking.tsx +11 -0
  134. package/studio/web/components/ApiKeyField.tsx +104 -0
  135. package/studio/web/components/AppShell.tsx +64 -0
  136. package/studio/web/components/ApprovalNotice.tsx +65 -0
  137. package/studio/web/components/AvatarGroupIcon.tsx +22 -0
  138. package/studio/web/components/AvatarNameField.tsx +86 -0
  139. package/studio/web/components/AvatarPicker.tsx +84 -0
  140. package/studio/web/components/BrandLogo.tsx +16 -0
  141. package/studio/web/components/CartesiaPlanSetting.tsx +90 -0
  142. package/studio/web/components/ClaudeWalking.tsx +32 -0
  143. package/studio/web/components/CloneVoiceDialog/GuidedScript.tsx +39 -0
  144. package/studio/web/components/CloneVoiceDialog/LanguageBar.tsx +37 -0
  145. package/studio/web/components/CloneVoiceDialog/LevelMeter.tsx +31 -0
  146. package/studio/web/components/CloneVoiceDialog/ProviderChoice.tsx +81 -0
  147. package/studio/web/components/CloneVoiceDialog/QualityPanel.tsx +62 -0
  148. package/studio/web/components/CloneVoiceDialog/RecordStep.tsx +50 -0
  149. package/studio/web/components/CloneVoiceDialog/RecorderBar.tsx +79 -0
  150. package/studio/web/components/CloneVoiceDialog/RedoSummary.tsx +54 -0
  151. package/studio/web/components/CloneVoiceDialog/SaveStep.tsx +91 -0
  152. package/studio/web/components/CloneVoiceDialog/SourceBar.tsx +30 -0
  153. package/studio/web/components/CloneVoiceDialog/index.tsx +141 -0
  154. package/studio/web/components/CloneVoiceDialog/types.ts +28 -0
  155. package/studio/web/components/CloneVoiceDialog/useCloneVoice.ts +528 -0
  156. package/studio/web/components/ConnectionSignals.tsx +51 -0
  157. package/studio/web/components/EditVoiceDialog/EditVoiceFooter.tsx +72 -0
  158. package/studio/web/components/EditVoiceDialog/ProviderCards.tsx +81 -0
  159. package/studio/web/components/EditVoiceDialog/index.tsx +256 -0
  160. package/studio/web/components/ErrorBanner.tsx +115 -0
  161. package/studio/web/components/FinishedTask.tsx +41 -0
  162. package/studio/web/components/FishModelSetting.tsx +69 -0
  163. package/studio/web/components/FishPriceSetting.tsx +44 -0
  164. package/studio/web/components/HumanBanner.tsx +64 -0
  165. package/studio/web/components/Lightbox.tsx +41 -0
  166. package/studio/web/components/LogStream.tsx +42 -0
  167. package/studio/web/components/Markdown.tsx +21 -0
  168. package/studio/web/components/MissingDmsPanel/BatchSend.tsx +137 -0
  169. package/studio/web/components/MissingDmsPanel/CommentCard.tsx +168 -0
  170. package/studio/web/components/MissingDmsPanel/CommentFeed.tsx +45 -0
  171. package/studio/web/components/MissingDmsPanel/DmBubble.tsx +38 -0
  172. package/studio/web/components/MissingDmsPanel/ReplyComposer.tsx +63 -0
  173. package/studio/web/components/MissingDmsPanel/index.tsx +98 -0
  174. package/studio/web/components/NotFound.tsx +48 -0
  175. package/studio/web/components/Omni/OmniAvatarPicker.tsx +92 -0
  176. package/studio/web/components/Omni/OmniCards.tsx +202 -0
  177. package/studio/web/components/Omni/OmniGlow.tsx +183 -0
  178. package/studio/web/components/Omni/OmniHistory.tsx +119 -0
  179. package/studio/web/components/Omni/OmniHotword.tsx +40 -0
  180. package/studio/web/components/Omni/OmniMicSelect.tsx +92 -0
  181. package/studio/web/components/Omni/OmniVoiceSample.tsx +81 -0
  182. package/studio/web/components/Omni/OmniWidget.tsx +743 -0
  183. package/studio/web/components/Omni/PendingActions.tsx +200 -0
  184. package/studio/web/components/Omni/Transcript.tsx +127 -0
  185. package/studio/web/components/OmnichatAccountStatus.tsx +87 -0
  186. package/studio/web/components/OmnichatRulePanel/RuleConfig.tsx +150 -0
  187. package/studio/web/components/OmnichatRulePanel/RuleDryRun.tsx +15 -0
  188. package/studio/web/components/OmnichatRulePanel/RuleEnableConfirm.tsx +42 -0
  189. package/studio/web/components/OmnichatRulePanel/RuleSkeleton.tsx +18 -0
  190. package/studio/web/components/OmnichatRulePanel/RuleStatus.tsx +55 -0
  191. package/studio/web/components/OmnichatRulePanel/index.tsx +115 -0
  192. package/studio/web/components/OmnichatRulePanel/rule-steps.ts +67 -0
  193. package/studio/web/components/OmnichatRulePanel/steps/MessageStep.tsx +91 -0
  194. package/studio/web/components/OmnichatRulePanel/steps/RepliesStep.tsx +201 -0
  195. package/studio/web/components/OmnichatRulePanel/steps/TriggerStep.tsx +76 -0
  196. package/studio/web/components/OmnichatRulePanel/steps/types.ts +11 -0
  197. package/studio/web/components/Palette.tsx +17 -0
  198. package/studio/web/components/PlatformCard.tsx +109 -0
  199. package/studio/web/components/PlatformIcon.tsx +19 -0
  200. package/studio/web/components/ProviderCard.tsx +80 -0
  201. package/studio/web/components/ProviderDetail.tsx +367 -0
  202. package/studio/web/components/ProviderLogo.tsx +20 -0
  203. package/studio/web/components/QueuePanel.tsx +77 -0
  204. package/studio/web/components/ReferenceActions.tsx +89 -0
  205. package/studio/web/components/ReferencePicker.tsx +136 -0
  206. package/studio/web/components/ResultMessage.tsx +7 -0
  207. package/studio/web/components/RuleForm.tsx +138 -0
  208. package/studio/web/components/RuleLog.tsx +151 -0
  209. package/studio/web/components/RunningTask.tsx +23 -0
  210. package/studio/web/components/SampleList.tsx +55 -0
  211. package/studio/web/components/SessionPanel.tsx +352 -0
  212. package/studio/web/components/SettingRow.tsx +14 -0
  213. package/studio/web/components/SettingsCategorySkeleton.tsx +25 -0
  214. package/studio/web/components/SidePanel.tsx +77 -0
  215. package/studio/web/components/Sidebar.tsx +289 -0
  216. package/studio/web/components/StageStepper.tsx +87 -0
  217. package/studio/web/components/StudioOffline.tsx +80 -0
  218. package/studio/web/components/TaskName.tsx +17 -0
  219. package/studio/web/components/TopBanners.tsx +30 -0
  220. package/studio/web/components/VideoOmnichatPanel.tsx +287 -0
  221. package/studio/web/components/VoiceAvatar.tsx +33 -0
  222. package/studio/web/components/VoiceCarousel.tsx +196 -0
  223. package/studio/web/components/VoiceCategory.tsx +9 -0
  224. package/studio/web/components/VoiceModal.tsx +39 -0
  225. package/studio/web/components/VoiceProfileCard.tsx +75 -0
  226. package/studio/web/components/VoiceProfilePicker.tsx +107 -0
  227. package/studio/web/components/VoiceProfilesSettings.tsx +150 -0
  228. package/studio/web/components/VoiceProviderCard.tsx +118 -0
  229. package/studio/web/components/VoiceProvidersCard.tsx +26 -0
  230. package/studio/web/components/WaitList.tsx +21 -0
  231. package/studio/web/components/icons.tsx +247 -0
  232. package/studio/web/components/ui/accordion.tsx +47 -0
  233. package/studio/web/components/ui/badge.tsx +18 -0
  234. package/studio/web/components/ui/calendar.tsx +43 -0
  235. package/studio/web/components/ui/chart.tsx +229 -0
  236. package/studio/web/components/ui/checkbox.tsx +26 -0
  237. package/studio/web/components/ui/cx.ts +2 -0
  238. package/studio/web/components/ui/date-time-picker.tsx +84 -0
  239. package/studio/web/components/ui/panel.tsx +23 -0
  240. package/studio/web/components/ui/picker.tsx +58 -0
  241. package/studio/web/components/ui/popover.tsx +24 -0
  242. package/studio/web/components/ui/select.tsx +89 -0
  243. package/studio/web/components/ui/skeleton.tsx +10 -0
  244. package/studio/web/components/ui/slider.tsx +68 -0
  245. package/studio/web/components/ui/switch.tsx +13 -0
  246. package/studio/web/components/ui/tooltip.tsx +59 -0
  247. package/studio/web/hooks/useAccounts.ts +27 -0
  248. package/studio/web/hooks/useAdmin.ts +12 -0
  249. package/studio/web/hooks/useAnalytics.ts +21 -0
  250. package/studio/web/hooks/useAvatarAudioReactive.ts +87 -0
  251. package/studio/web/hooks/useBrowserConnect.ts +48 -0
  252. package/studio/web/hooks/useClonePlan.ts +14 -0
  253. package/studio/web/hooks/useConnected.ts +7 -0
  254. package/studio/web/hooks/useLiveQuery.ts +29 -0
  255. package/studio/web/hooks/useMenuCollapsed.ts +32 -0
  256. package/studio/web/hooks/useMicDevices.ts +53 -0
  257. package/studio/web/hooks/useMissingDms.ts +211 -0
  258. package/studio/web/hooks/useMissingSetupSteps.ts +26 -0
  259. package/studio/web/hooks/useNow.ts +11 -0
  260. package/studio/web/hooks/useOmniAgent.ts +278 -0
  261. package/studio/web/hooks/useOmniClaude.ts +124 -0
  262. package/studio/web/hooks/useOmniDock.ts +142 -0
  263. package/studio/web/hooks/useOmniGreeting.ts +60 -0
  264. package/studio/web/hooks/useOmniHotword.ts +128 -0
  265. package/studio/web/hooks/useOmnichat.ts +26 -0
  266. package/studio/web/hooks/useOnboarding.ts +27 -0
  267. package/studio/web/hooks/usePost.ts +23 -0
  268. package/studio/web/hooks/useQueue.ts +10 -0
  269. package/studio/web/hooks/useReferences.ts +20 -0
  270. package/studio/web/hooks/useRuleEditor.ts +101 -0
  271. package/studio/web/hooks/useRunner.ts +24 -0
  272. package/studio/web/hooks/useSaveAction.ts +23 -0
  273. package/studio/web/hooks/useSchedule.ts +11 -0
  274. package/studio/web/hooks/useServices.ts +10 -0
  275. package/studio/web/hooks/useSessions.ts +15 -0
  276. package/studio/web/hooks/useSettings.ts +11 -0
  277. package/studio/web/hooks/useSettingsSection.ts +30 -0
  278. package/studio/web/hooks/useSidePanel.ts +23 -0
  279. package/studio/web/hooks/useSound.ts +30 -0
  280. package/studio/web/hooks/useUsage.ts +11 -0
  281. package/studio/web/hooks/useVideoVoice.ts +36 -0
  282. package/studio/web/hooks/useVideos.ts +21 -0
  283. package/studio/web/hooks/useVoiceProfilePreview.ts +52 -0
  284. package/studio/web/hooks/useVoiceProfiles.ts +7 -0
  285. package/studio/web/hooks/useVoiceRunning.ts +10 -0
  286. package/studio/web/hooks/useVoiceStudioClosed.ts +8 -0
  287. package/studio/web/index.html +19 -0
  288. package/studio/web/lib/agent.ts +7 -0
  289. package/studio/web/lib/alerts.ts +210 -0
  290. package/studio/web/lib/analytics-metrics.ts +351 -0
  291. package/studio/web/lib/api.ts +70 -0
  292. package/studio/web/lib/audio.ts +39 -0
  293. package/studio/web/lib/avatars.ts +41 -0
  294. package/studio/web/lib/calendar.ts +218 -0
  295. package/studio/web/lib/caption-position.ts +249 -0
  296. package/studio/web/lib/carousel.ts +24 -0
  297. package/studio/web/lib/chime.ts +42 -0
  298. package/studio/web/lib/clone-voice.ts +55 -0
  299. package/studio/web/lib/export.ts +11 -0
  300. package/studio/web/lib/files.ts +8 -0
  301. package/studio/web/lib/format.ts +93 -0
  302. package/studio/web/lib/media.ts +29 -0
  303. package/studio/web/lib/mic-device.ts +72 -0
  304. package/studio/web/lib/missing-dms.ts +70 -0
  305. package/studio/web/lib/omni-cards.ts +42 -0
  306. package/studio/web/lib/omni-cascade.ts +1067 -0
  307. package/studio/web/lib/omni-greeting-audio.ts +24 -0
  308. package/studio/web/lib/omni-hotword.ts +231 -0
  309. package/studio/web/lib/omni-panel.ts +67 -0
  310. package/studio/web/lib/omni-realtime.ts +811 -0
  311. package/studio/web/lib/omni-ui.ts +402 -0
  312. package/studio/web/lib/omni-wait.ts +174 -0
  313. package/studio/web/lib/omnichat-api.ts +44 -0
  314. package/studio/web/lib/orb.ts +270 -0
  315. package/studio/web/lib/pcm-recorder.ts +115 -0
  316. package/studio/web/lib/platforms.ts +17 -0
  317. package/studio/web/lib/providers.ts +27 -0
  318. package/studio/web/lib/publish-draft.ts +52 -0
  319. package/studio/web/lib/publish-settings.ts +81 -0
  320. package/studio/web/lib/query-client.ts +122 -0
  321. package/studio/web/lib/references.ts +13 -0
  322. package/studio/web/lib/services.ts +40 -0
  323. package/studio/web/lib/sessions.ts +103 -0
  324. package/studio/web/lib/settings-categories.ts +58 -0
  325. package/studio/web/lib/sound-audio.ts +33 -0
  326. package/studio/web/lib/sound-timeline.ts +291 -0
  327. package/studio/web/lib/sse.ts +86 -0
  328. package/studio/web/lib/stage-history.ts +141 -0
  329. package/studio/web/lib/stages.ts +344 -0
  330. package/studio/web/lib/studio-offline.ts +60 -0
  331. package/studio/web/lib/upload.ts +24 -0
  332. package/studio/web/lib/video-tabs.ts +118 -0
  333. package/studio/web/lib/voice-profile-draft.ts +34 -0
  334. package/studio/web/lib/voice-profiles.ts +3 -0
  335. package/studio/web/main.tsx +14 -0
  336. package/studio/web/pages/AdminPage/index.tsx +123 -0
  337. package/studio/web/pages/AgentPage/components/Measurements.tsx +102 -0
  338. package/studio/web/pages/AgentPage/index.tsx +28 -0
  339. package/studio/web/pages/AnalyticsPage/components/About.tsx +52 -0
  340. package/studio/web/pages/AnalyticsPage/components/ChannelCards.tsx +106 -0
  341. package/studio/web/pages/AnalyticsPage/components/ChannelView.tsx +137 -0
  342. package/studio/web/pages/AnalyticsPage/components/CollectionStatus.tsx +46 -0
  343. package/studio/web/pages/AnalyticsPage/components/Comparison.tsx +68 -0
  344. package/studio/web/pages/AnalyticsPage/components/Diagnosis.tsx +50 -0
  345. package/studio/web/pages/AnalyticsPage/components/Highlights.tsx +49 -0
  346. package/studio/web/pages/AnalyticsPage/components/Hint.tsx +11 -0
  347. package/studio/web/pages/AnalyticsPage/components/HookVsBody.tsx +100 -0
  348. package/studio/web/pages/AnalyticsPage/components/HourlyWave.tsx +133 -0
  349. package/studio/web/pages/AnalyticsPage/components/Insights.tsx +70 -0
  350. package/studio/web/pages/AnalyticsPage/components/MetricCard.tsx +46 -0
  351. package/studio/web/pages/AnalyticsPage/components/PlanSection.tsx +40 -0
  352. package/studio/web/pages/AnalyticsPage/components/ProgressionChart.tsx +155 -0
  353. package/studio/web/pages/AnalyticsPage/components/ReelBarsChart.tsx +154 -0
  354. package/studio/web/pages/AnalyticsPage/components/ReelThumb.tsx +19 -0
  355. package/studio/web/pages/AnalyticsPage/components/ReelView.tsx +290 -0
  356. package/studio/web/pages/AnalyticsPage/components/ReelsTable.tsx +269 -0
  357. package/studio/web/pages/AnalyticsPage/components/RequestWithFocus.tsx +38 -0
  358. package/studio/web/pages/AnalyticsPage/components/SegmentedControl.tsx +35 -0
  359. package/studio/web/pages/AnalyticsPage/components/VsMedian.tsx +31 -0
  360. package/studio/web/pages/AnalyticsPage/index.tsx +17 -0
  361. package/studio/web/pages/GettingStartedPage/index.tsx +174 -0
  362. package/studio/web/pages/NewVideoPage/components/DeliverablesPicker.tsx +62 -0
  363. package/studio/web/pages/NewVideoPage/components/FormatPicker.tsx +33 -0
  364. package/studio/web/pages/NewVideoPage/index.tsx +133 -0
  365. package/studio/web/pages/NotFoundPage/index.tsx +9 -0
  366. package/studio/web/pages/OmnichatPage/components/NewFromLink.tsx +59 -0
  367. package/studio/web/pages/OmnichatPage/components/RuleListItem.tsx +64 -0
  368. package/studio/web/pages/OmnichatPage/components/RulePreview.tsx +14 -0
  369. package/studio/web/pages/OmnichatPage/components/RuleView.tsx +88 -0
  370. package/studio/web/pages/OmnichatPage/index.tsx +153 -0
  371. package/studio/web/pages/QueuePage/index.tsx +22 -0
  372. package/studio/web/pages/ReferencePage/components/ReferenceTexts.tsx +131 -0
  373. package/studio/web/pages/ReferencePage/index.tsx +216 -0
  374. package/studio/web/pages/ReferencesPage/components/NewReferenceForm.tsx +150 -0
  375. package/studio/web/pages/ReferencesPage/components/ReferenceCard.tsx +42 -0
  376. package/studio/web/pages/ReferencesPage/components/ReferenceGridSkeleton.tsx +31 -0
  377. package/studio/web/pages/ReferencesPage/index.tsx +67 -0
  378. package/studio/web/pages/SchedulePage/components/CalendarSkeleton.tsx +18 -0
  379. package/studio/web/pages/SchedulePage/components/DayView.tsx +177 -0
  380. package/studio/web/pages/SchedulePage/components/HourPicker.tsx +103 -0
  381. package/studio/web/pages/SchedulePage/components/MonthDayCell.tsx +111 -0
  382. package/studio/web/pages/SchedulePage/components/MonthView.tsx +47 -0
  383. package/studio/web/pages/SchedulePage/components/PlatformIcons.tsx +12 -0
  384. package/studio/web/pages/SchedulePage/components/PostThumb.tsx +15 -0
  385. package/studio/web/pages/SchedulePage/components/WeekColumn.tsx +75 -0
  386. package/studio/web/pages/SchedulePage/components/WeekView.tsx +35 -0
  387. package/studio/web/pages/SchedulePage/index.tsx +285 -0
  388. package/studio/web/pages/SettingsPage/components/AgentAccounts.tsx +263 -0
  389. package/studio/web/pages/SettingsPage/components/AgentCategory.tsx +20 -0
  390. package/studio/web/pages/SettingsPage/components/ModelPicker.tsx +49 -0
  391. package/studio/web/pages/SettingsPage/components/ModelsSettings.tsx +138 -0
  392. package/studio/web/pages/SettingsPage/components/PlatformsCategory.tsx +23 -0
  393. package/studio/web/pages/SettingsPage/components/PublishingCategory/AccountStatus.tsx +29 -0
  394. package/studio/web/pages/SettingsPage/components/PublishingCategory/AutoPublishPanel.tsx +90 -0
  395. package/studio/web/pages/SettingsPage/components/PublishingCategory/BrowserConnect.tsx +62 -0
  396. package/studio/web/pages/SettingsPage/components/PublishingCategory/CheckField.tsx +19 -0
  397. package/studio/web/pages/SettingsPage/components/PublishingCategory/InstagramPanel.tsx +113 -0
  398. package/studio/web/pages/SettingsPage/components/PublishingCategory/OmnichatSettingsPanel.tsx +146 -0
  399. package/studio/web/pages/SettingsPage/components/PublishingCategory/SaveBar.tsx +33 -0
  400. package/studio/web/pages/SettingsPage/components/PublishingCategory/SchedulePanel.tsx +132 -0
  401. package/studio/web/pages/SettingsPage/components/PublishingCategory/SettingsCard.tsx +47 -0
  402. package/studio/web/pages/SettingsPage/components/PublishingCategory/SettingsCardGroup.tsx +19 -0
  403. package/studio/web/pages/SettingsPage/components/PublishingCategory/TextPanel.tsx +55 -0
  404. package/studio/web/pages/SettingsPage/components/PublishingCategory/TiktokPanel.tsx +123 -0
  405. package/studio/web/pages/SettingsPage/components/PublishingCategory/YoutubePanel.tsx +100 -0
  406. package/studio/web/pages/SettingsPage/components/PublishingCategory/badges.tsx +15 -0
  407. package/studio/web/pages/SettingsPage/components/PublishingCategory/index.tsx +40 -0
  408. package/studio/web/pages/SettingsPage/components/PublishingCategory/types.ts +10 -0
  409. package/studio/web/pages/SettingsPage/components/UsageCategory.tsx +389 -0
  410. package/studio/web/pages/SettingsPage/components/VoiceProvidersCategory.tsx +97 -0
  411. package/studio/web/pages/SettingsPage/index.tsx +85 -0
  412. package/studio/web/pages/VideoPage/components/AudioPlayer.tsx +113 -0
  413. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/AxisField.tsx +50 -0
  414. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionList.tsx +56 -0
  415. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionListItem.tsx +92 -0
  416. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionMargins.tsx +57 -0
  417. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionStyleFields.tsx +70 -0
  418. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionTextForm.tsx +87 -0
  419. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/ColorField.tsx +37 -0
  420. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/MarginField.tsx +59 -0
  421. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/NumberField.tsx +57 -0
  422. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/PositionControls.tsx +140 -0
  423. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/captionEditor.ts +215 -0
  424. package/studio/web/pages/VideoPage/components/CaptionPositionEditor/useCaptionPosition.ts +154 -0
  425. package/studio/web/pages/VideoPage/components/CarouselChangeRequest.tsx +72 -0
  426. package/studio/web/pages/VideoPage/components/CarouselCompositionStage.tsx +80 -0
  427. package/studio/web/pages/VideoPage/components/CarouselCreate.tsx +63 -0
  428. package/studio/web/pages/VideoPage/components/CarouselMissing.tsx +19 -0
  429. package/studio/web/pages/VideoPage/components/CarouselPublishStage.tsx +173 -0
  430. package/studio/web/pages/VideoPage/components/CarouselScriptStage.tsx +82 -0
  431. package/studio/web/pages/VideoPage/components/CarouselSlideCard.tsx +49 -0
  432. package/studio/web/pages/VideoPage/components/CarouselViewer.tsx +55 -0
  433. package/studio/web/pages/VideoPage/components/ChangedVoices.tsx +53 -0
  434. package/studio/web/pages/VideoPage/components/CompositionStage.tsx +78 -0
  435. package/studio/web/pages/VideoPage/components/CoverPicker.tsx +32 -0
  436. package/studio/web/pages/VideoPage/components/EditorStage.tsx +53 -0
  437. package/studio/web/pages/VideoPage/components/LineTakes.tsx +160 -0
  438. package/studio/web/pages/VideoPage/components/LineTextEditor.tsx +124 -0
  439. package/studio/web/pages/VideoPage/components/LineVoicePicker.tsx +37 -0
  440. package/studio/web/pages/VideoPage/components/MediaImage.tsx +25 -0
  441. package/studio/web/pages/VideoPage/components/MotionScriptStage.tsx +39 -0
  442. package/studio/web/pages/VideoPage/components/NarrationStage.tsx +70 -0
  443. package/studio/web/pages/VideoPage/components/PublishForm.tsx +387 -0
  444. package/studio/web/pages/VideoPage/components/PublishStage.tsx +76 -0
  445. package/studio/web/pages/VideoPage/components/PublishText.tsx +149 -0
  446. package/studio/web/pages/VideoPage/components/ScenesApprovalPanel.tsx +278 -0
  447. package/studio/web/pages/VideoPage/components/ScheduledInfo.tsx +72 -0
  448. package/studio/web/pages/VideoPage/components/ScriptApprovalPanel.tsx +189 -0
  449. package/studio/web/pages/VideoPage/components/ScriptStage.tsx +17 -0
  450. package/studio/web/pages/VideoPage/components/SequencePlayer.tsx +146 -0
  451. package/studio/web/pages/VideoPage/components/SoundTimeline/AddSound.tsx +117 -0
  452. package/studio/web/pages/VideoPage/components/SoundTimeline/AreaSelection.tsx +74 -0
  453. package/studio/web/pages/VideoPage/components/SoundTimeline/BedPanel.tsx +94 -0
  454. package/studio/web/pages/VideoPage/components/SoundTimeline/BedRow.tsx +45 -0
  455. package/studio/web/pages/VideoPage/components/SoundTimeline/CaptionOverlay.tsx +44 -0
  456. package/studio/web/pages/VideoPage/components/SoundTimeline/CaptionSaveBar.tsx +32 -0
  457. package/studio/web/pages/VideoPage/components/SoundTimeline/CaptionsPanel.tsx +22 -0
  458. package/studio/web/pages/VideoPage/components/SoundTimeline/ClipBlock.tsx +111 -0
  459. package/studio/web/pages/VideoPage/components/SoundTimeline/ClipPanel.tsx +76 -0
  460. package/studio/web/pages/VideoPage/components/SoundTimeline/CutsPanel.tsx +44 -0
  461. package/studio/web/pages/VideoPage/components/SoundTimeline/EditorTabBar.tsx +73 -0
  462. package/studio/web/pages/VideoPage/components/SoundTimeline/EffectChoice.tsx +46 -0
  463. package/studio/web/pages/VideoPage/components/SoundTimeline/EffectItem.tsx +89 -0
  464. package/studio/web/pages/VideoPage/components/SoundTimeline/EffectPanel.tsx +232 -0
  465. package/studio/web/pages/VideoPage/components/SoundTimeline/EffectsRow.tsx +21 -0
  466. package/studio/web/pages/VideoPage/components/SoundTimeline/Lane.tsx +39 -0
  467. package/studio/web/pages/VideoPage/components/SoundTimeline/MarkerRow.tsx +40 -0
  468. package/studio/web/pages/VideoPage/components/SoundTimeline/MuteButton.tsx +36 -0
  469. package/studio/web/pages/VideoPage/components/SoundTimeline/NumberInput.tsx +37 -0
  470. package/studio/web/pages/VideoPage/components/SoundTimeline/PlanWarnings.tsx +19 -0
  471. package/studio/web/pages/VideoPage/components/SoundTimeline/PlayerResizeHandle.tsx +50 -0
  472. package/studio/web/pages/VideoPage/components/SoundTimeline/PreviewControls.tsx +51 -0
  473. package/studio/web/pages/VideoPage/components/SoundTimeline/SceneRow.tsx +54 -0
  474. package/studio/web/pages/VideoPage/components/SoundTimeline/SettingsPanel.tsx +65 -0
  475. package/studio/web/pages/VideoPage/components/SoundTimeline/SoundLibrary.tsx +99 -0
  476. package/studio/web/pages/VideoPage/components/SoundTimeline/SoundPreview.tsx +82 -0
  477. package/studio/web/pages/VideoPage/components/SoundTimeline/SpeedPanel.tsx +128 -0
  478. package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineDock.tsx +56 -0
  479. package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineFooter.tsx +26 -0
  480. package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineSkeleton.tsx +21 -0
  481. package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineToolbar.tsx +160 -0
  482. package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineTracks.tsx +121 -0
  483. package/studio/web/pages/VideoPage/components/SoundTimeline/TrackSidebar.tsx +30 -0
  484. package/studio/web/pages/VideoPage/components/SoundTimeline/VoiceRow.tsx +53 -0
  485. package/studio/web/pages/VideoPage/components/SoundTimeline/Waveform.tsx +97 -0
  486. package/studio/web/pages/VideoPage/components/SoundTimeline/clipActions.ts +50 -0
  487. package/studio/web/pages/VideoPage/components/SoundTimeline/effectActions.ts +161 -0
  488. package/studio/web/pages/VideoPage/components/SoundTimeline/index.tsx +161 -0
  489. package/studio/web/pages/VideoPage/components/SoundTimeline/timelineGeometry.ts +45 -0
  490. package/studio/web/pages/VideoPage/components/SoundTimeline/types.ts +43 -0
  491. package/studio/web/pages/VideoPage/components/SoundTimeline/useAutosave.ts +107 -0
  492. package/studio/web/pages/VideoPage/components/SoundTimeline/useEditorShortcuts.ts +168 -0
  493. package/studio/web/pages/VideoPage/components/SoundTimeline/useFitHeight.ts +40 -0
  494. package/studio/web/pages/VideoPage/components/SoundTimeline/useFollowPlayhead.ts +21 -0
  495. package/studio/web/pages/VideoPage/components/SoundTimeline/useListenMix.ts +43 -0
  496. package/studio/web/pages/VideoPage/components/SoundTimeline/usePlayback.ts +231 -0
  497. package/studio/web/pages/VideoPage/components/SoundTimeline/usePlayerWidth.ts +27 -0
  498. package/studio/web/pages/VideoPage/components/SoundTimeline/useSoundData.ts +124 -0
  499. package/studio/web/pages/VideoPage/components/SoundTimeline/useSoundTimeline.ts +511 -0
  500. package/studio/web/pages/VideoPage/components/StageDrawer/CompareVersions.tsx +111 -0
  501. package/studio/web/pages/VideoPage/components/StageDrawer/VersionCard.tsx +81 -0
  502. package/studio/web/pages/VideoPage/components/StageDrawer/VersionMedia.tsx +24 -0
  503. package/studio/web/pages/VideoPage/components/StageDrawer/VersionText.tsx +15 -0
  504. package/studio/web/pages/VideoPage/components/StageDrawer/index.tsx +109 -0
  505. package/studio/web/pages/VideoPage/components/StageProcess.tsx +126 -0
  506. package/studio/web/pages/VideoPage/components/StageResult.tsx +69 -0
  507. package/studio/web/pages/VideoPage/components/SwapReference.tsx +92 -0
  508. package/studio/web/pages/VideoPage/components/ThumbnailPanel.tsx +252 -0
  509. package/studio/web/pages/VideoPage/components/TimingPanel.tsx +89 -0
  510. package/studio/web/pages/VideoPage/components/VideoPlayer.tsx +18 -0
  511. package/studio/web/pages/VideoPage/components/VideoSkeleton.tsx +50 -0
  512. package/studio/web/pages/VideoPage/components/VideoVoiceInfo.tsx +33 -0
  513. package/studio/web/pages/VideoPage/components/VideoVoicePicker.tsx +165 -0
  514. package/studio/web/pages/VideoPage/components/VoicePauseBanner.tsx +56 -0
  515. package/studio/web/pages/VideoPage/components/WithLogo.tsx +10 -0
  516. package/studio/web/pages/VideoPage/index.tsx +295 -0
  517. package/studio/web/pages/VideosPage/components/PublishedOn.tsx +85 -0
  518. package/studio/web/pages/VideosPage/components/ServicesPanel.tsx +81 -0
  519. package/studio/web/pages/VideosPage/components/SessionsPanel.tsx +62 -0
  520. package/studio/web/pages/VideosPage/components/VideoListSkeleton.tsx +25 -0
  521. package/studio/web/pages/VideosPage/components/VideoRow.tsx +122 -0
  522. package/studio/web/pages/VideosPage/index.tsx +134 -0
  523. package/studio/web/pages/VoicePage/index.tsx +28 -0
  524. package/studio/web/router.tsx +201 -0
  525. package/studio/web/styles/base/elements.css +55 -0
  526. package/studio/web/styles/base/utilities.css +25 -0
  527. package/studio/web/styles/components/badge.css +33 -0
  528. package/studio/web/styles/components/claude-running.css +27 -0
  529. package/studio/web/styles/components/claude-session.css +212 -0
  530. package/studio/web/styles/components/claude-walking.css +92 -0
  531. package/studio/web/styles/components/clone-voice-save.css +136 -0
  532. package/studio/web/styles/components/clone-voice.css +379 -0
  533. package/studio/web/styles/components/controls.css +70 -0
  534. package/studio/web/styles/components/data-and-image.css +54 -0
  535. package/studio/web/styles/components/forms.css +132 -0
  536. package/studio/web/styles/components/human-banner.css +99 -0
  537. package/studio/web/styles/components/lightbox.css +50 -0
  538. package/studio/web/styles/components/markdown.css +68 -0
  539. package/studio/web/styles/components/modal.css +70 -0
  540. package/studio/web/styles/components/omni-cards.css +105 -0
  541. package/studio/web/styles/components/omni.css +859 -0
  542. package/studio/web/styles/components/omnichat.css +538 -0
  543. package/studio/web/styles/components/panel.css +115 -0
  544. package/studio/web/styles/components/platform-card.css +140 -0
  545. package/studio/web/styles/components/provider-card.css +132 -0
  546. package/studio/web/styles/components/queue.css +185 -0
  547. package/studio/web/styles/components/reference-actions.css +133 -0
  548. package/studio/web/styles/components/reference-picker.css +146 -0
  549. package/studio/web/styles/components/results-drawer.css +224 -0
  550. package/studio/web/styles/components/segmented.css +115 -0
  551. package/studio/web/styles/components/side-panel-tab.css +23 -0
  552. package/studio/web/styles/components/status-signals.css +66 -0
  553. package/studio/web/styles/components/stepper.css +208 -0
  554. package/studio/web/styles/components/table.css +19 -0
  555. package/studio/web/styles/components/tabs.css +24 -0
  556. package/studio/web/styles/components/ui/accordion.css +71 -0
  557. package/studio/web/styles/components/ui/chart.css +162 -0
  558. package/studio/web/styles/components/ui/checkbox.css +37 -0
  559. package/studio/web/styles/components/ui/date-picker.css +153 -0
  560. package/studio/web/styles/components/ui/select.css +110 -0
  561. package/studio/web/styles/components/ui/skeleton.css +25 -0
  562. package/studio/web/styles/components/ui/slider.css +81 -0
  563. package/studio/web/styles/components/ui/switch.css +41 -0
  564. package/studio/web/styles/components/ui/tooltip.css +24 -0
  565. package/studio/web/styles/components/voice-carousel.css +255 -0
  566. package/studio/web/styles/components/voice-editor.css +179 -0
  567. package/studio/web/styles/components/voice-grid.css +56 -0
  568. package/studio/web/styles/components/voice-profiles.css +192 -0
  569. package/studio/web/styles/design-system.md +136 -0
  570. package/studio/web/styles/index.css +116 -0
  571. package/studio/web/styles/layout/page.css +41 -0
  572. package/studio/web/styles/layout/sidebar-groups.css +39 -0
  573. package/studio/web/styles/layout/sidebar.css +111 -0
  574. package/studio/web/styles/pages/agent.css +26 -0
  575. package/studio/web/styles/pages/analytics/dashboard.css +614 -0
  576. package/studio/web/styles/pages/analytics/insights.css +48 -0
  577. package/studio/web/styles/pages/getting-started.css +166 -0
  578. package/studio/web/styles/pages/new-video/form.css +32 -0
  579. package/studio/web/styles/pages/not-found.css +59 -0
  580. package/studio/web/styles/pages/references.css +204 -0
  581. package/studio/web/styles/pages/schedule/calendar.css +541 -0
  582. package/studio/web/styles/pages/schedule/chip-states.css +60 -0
  583. package/studio/web/styles/pages/settings/models.css +72 -0
  584. package/studio/web/styles/pages/settings/shell.css +361 -0
  585. package/studio/web/styles/pages/settings/usage.css +63 -0
  586. package/studio/web/styles/pages/studio-offline.css +105 -0
  587. package/studio/web/styles/pages/video/caption-controls.css +194 -0
  588. package/studio/web/styles/pages/video/captions-grid.css +70 -0
  589. package/studio/web/styles/pages/video/captions.css +79 -0
  590. package/studio/web/styles/pages/video/editor-chat.css +103 -0
  591. package/studio/web/styles/pages/video/export.css +50 -0
  592. package/studio/web/styles/pages/video/frames.css +29 -0
  593. package/studio/web/styles/pages/video/fullscreen-stage.css +400 -0
  594. package/studio/web/styles/pages/video/instagram-carousel.css +309 -0
  595. package/studio/web/styles/pages/video/layout.css +285 -0
  596. package/studio/web/styles/pages/video/narration.css +138 -0
  597. package/studio/web/styles/pages/video/preview-overview.css +11 -0
  598. package/studio/web/styles/pages/video/processing-notice.css +34 -0
  599. package/studio/web/styles/pages/video/publish-when.css +76 -0
  600. package/studio/web/styles/pages/video/publish.css +97 -0
  601. package/studio/web/styles/pages/video/result.css +96 -0
  602. package/studio/web/styles/pages/video/scenes.css +167 -0
  603. package/studio/web/styles/pages/video/sound-timeline.css +672 -0
  604. package/studio/web/styles/pages/video/sound-toolbar.css +149 -0
  605. package/studio/web/styles/pages/video/take-player.css +100 -0
  606. package/studio/web/styles/pages/video/thumbnail.css +157 -0
  607. package/studio/web/styles/pages/video/timeline.css +117 -0
  608. package/studio/web/styles/pages/video/voice-picker.css +14 -0
  609. package/studio/web/styles/pages/video-list/active-row.css +27 -0
  610. package/studio/web/styles/pages/video-list/card-link.css +49 -0
  611. package/studio/web/styles/pages/video-list/list.css +86 -0
  612. package/studio/web/styles/theme/identity/details.css +204 -0
  613. package/studio/web/styles/theme/identity/shell.css +249 -0
  614. package/studio/web/styles/theme/identity/surfaces.css +183 -0
  615. package/studio/web/styles/theme/identity/titles-and-buttons.css +120 -0
  616. package/studio/web/styles/theme/no-borders/blocks.css +208 -0
  617. package/studio/web/styles/theme/no-borders/controls.css +256 -0
  618. package/studio/web/styles/tokens.css +245 -0
  619. package/studio/web/types/api.ts +2 -0
  620. package/studio/web/types/assets.d.ts +9 -0
  621. package/templates/brief.md +27 -0
  622. package/templates/captions.html +204 -0
  623. package/templates/carousel-composition.md +47 -0
  624. package/templates/carousel-script.md +60 -0
  625. package/templates/components/voiceavatar/README.md +87 -0
  626. package/templates/components/voiceavatar/demo.html +50 -0
  627. package/templates/components/voiceavatar/voiceavatar.js +415 -0
  628. package/templates/motion.md +80 -0
  629. package/templates/playbook.md +43 -0
  630. package/templates/reference.md +123 -0
  631. package/templates/scene.html +112 -0
  632. package/templates/scenes.example.json +96 -0
  633. package/templates/script.md +63 -0
  634. package/templates/slide.html +71 -0
  635. package/templates/wireframe.html +91 -0
  636. package/tools/analysis.mjs +300 -0
  637. package/tools/approval.mjs +442 -0
  638. package/tools/assemble.mjs +942 -0
  639. package/tools/build-motion.mjs +437 -0
  640. package/tools/captions.mjs +246 -0
  641. package/tools/carousel.mjs +558 -0
  642. package/tools/compose.mjs +307 -0
  643. package/tools/cuts.mjs +74 -0
  644. package/tools/editor.mjs +419 -0
  645. package/tools/epidemic-capture.js +54 -0
  646. package/tools/fanout.mjs +69 -0
  647. package/tools/history.mjs +70 -0
  648. package/tools/history.py +61 -0
  649. package/tools/job-queue.mjs +180 -0
  650. package/tools/job_queue.py +430 -0
  651. package/tools/lib/agents.mjs +412 -0
  652. package/tools/lib/channel.mjs +399 -0
  653. package/tools/lib/claude-settings.mjs +67 -0
  654. package/tools/lib/cli.mjs +9 -0
  655. package/tools/lib/fanout.mjs +234 -0
  656. package/tools/lib/http.mjs +94 -0
  657. package/tools/lib/index.js +14 -0
  658. package/tools/lib/mcp-server.mjs +69 -0
  659. package/tools/lib/metrics/metrics.mjs +204 -0
  660. package/tools/lib/narration.mjs +15 -0
  661. package/tools/lib/oauth-client.mjs +295 -0
  662. package/tools/lib/omnichat/config.mjs +139 -0
  663. package/tools/lib/omnichat/errors.mjs +42 -0
  664. package/tools/lib/omnichat/extract.mjs +82 -0
  665. package/tools/lib/omnichat/gate.mjs +151 -0
  666. package/tools/lib/omnichat/manual.mjs +166 -0
  667. package/tools/lib/omnichat/match.mjs +78 -0
  668. package/tools/lib/omnichat/pass.mjs +393 -0
  669. package/tools/lib/omnichat/record.mjs +208 -0
  670. package/tools/lib/omnichat/text.mjs +315 -0
  671. package/tools/lib/omnichat/webhook.mjs +166 -0
  672. package/tools/lib/pairing.mjs +99 -0
  673. package/tools/lib/paths.mjs +41 -0
  674. package/tools/lib/platforms/instagram.mjs +469 -0
  675. package/tools/lib/platforms/tiktok.mjs +343 -0
  676. package/tools/lib/platforms/youtube.mjs +228 -0
  677. package/tools/lib/publish/publish.mjs +244 -0
  678. package/tools/lib/schedule/schedule.mjs +191 -0
  679. package/tools/lib/service.mjs +134 -0
  680. package/tools/lib/skill-client.mjs +126 -0
  681. package/tools/lib/skills-release.mjs +196 -0
  682. package/tools/lib/testing.mjs +52 -0
  683. package/tools/lib/up.mjs +187 -0
  684. package/tools/metrics.mjs +415 -0
  685. package/tools/models.mjs +134 -0
  686. package/tools/narrate.mjs +257 -0
  687. package/tools/omni.mjs +298 -0
  688. package/tools/omni_paths.py +12 -0
  689. package/tools/omnichat.mjs +1577 -0
  690. package/tools/omnivideo.py +1122 -0
  691. package/tools/package.mjs +130 -0
  692. package/tools/platforms.mjs +236 -0
  693. package/tools/premiere.mjs +533 -0
  694. package/tools/publish.mjs +1496 -0
  695. package/tools/reference.mjs +1408 -0
  696. package/tools/render.mjs +426 -0
  697. package/tools/runner.mjs +156 -0
  698. package/tools/setup.mjs +466 -0
  699. package/tools/skills-release.mjs +93 -0
  700. package/tools/sound.mjs +1323 -0
  701. package/tools/soundtrack.mjs +217 -0
  702. package/tools/thumbnail.mjs +271 -0
  703. package/tools/timing.mjs +108 -0
  704. package/tools/usage.py +628 -0
  705. package/tools/voice-envelope.mjs +185 -0
  706. package/tools/voice.py +448 -0
  707. package/tools/voice_sample.py +75 -0
  708. package/tools/wireframe.mjs +230 -0
@@ -0,0 +1,305 @@
1
+ # Publishing to YouTube, Instagram and TikTok
2
+
3
+ The **Publicar** (Publish) button lives in the studio's Publicar stage. Each
4
+ platform is a card with the icon, the photo and the @ of the connected account;
5
+ check one, two or all three. It writes the text to
6
+ `videos/<slug>/publication.json` and runs `tools/publish.mjs`, which uploads the
7
+ MP4 from `export/assembly.json` and writes back each platform's id and link. A
8
+ video that is already up on a platform doesn't go up again, unless you check
9
+ that platform again (`--again`).
10
+
11
+ Credentials live in `.env` (outside git). Each account is set up only once, in
12
+ Configurações (Settings) → Plataformas (Platforms) or in the terminal.
13
+
14
+ ## Title, description and post caption
15
+
16
+ They come out of the script on their own. When the video has no text yet, the
17
+ Publicar stage runs `node tools/publish.mjs text videos/<slug>`: Claude
18
+ (`claude -p`, in the studio sessions' config folder) reads `script.md` and writes
19
+ the title, description, post caption and tags. Without Claude, the title comes
20
+ from the script's heading, the description from the thesis and the caption from
21
+ the hook. Everything is editable in the studio, and "Escrever de novo a partir do
22
+ roteiro" (Rewrite from the script) (`--redo`) replaces what is there. Publishing
23
+ also writes the text before uploading, if the title is missing.
24
+
25
+ The **post caption** is the same on Instagram and TikTok. If empty, the title
26
+ plus the description is used. Each platform's footer and the fixed hashtags go
27
+ at the end.
28
+
29
+ ```bash
30
+ node tools/publish.mjs status # what is connected
31
+ ```
32
+
33
+ ## YouTube
34
+
35
+ 1. **Project and API.** At [console.cloud.google.com](https://console.cloud.google.com),
36
+ create a project (for example `omnivideo`) and enable the **YouTube Data API v3**
37
+ under APIs & Services → Library.
38
+ 2. **Consent screen.** In Google Auth Platform (or APIs & Services → OAuth
39
+ consent screen): type **External**, app name, your email. Under Audience, set
40
+ the app to **In production**. In "Testing", the login expires every 7 days.
41
+ Since the app isn't verified, Google shows a warning at login ("Google hasn't
42
+ verified this app"). For your own use, click Advanced → continue.
43
+ 3. **OAuth client.** Under Clients → Create client, type **Desktop app**. Copy
44
+ the ID and the secret into `.env`:
45
+ ```
46
+ YOUTUBE_CLIENT_ID=…apps.googleusercontent.com
47
+ YOUTUBE_CLIENT_SECRET=GOCSPX-…
48
+ ```
49
+ 4. **Login.** `node tools/publish.mjs auth youtube`. The browser opens: pick the
50
+ **channel's** account and allow. The refresh token goes to `.env`
51
+ (`YOUTUBE_REFRESH_TOKEN`), and the command shows the channel name.
52
+ `--browser Dia` opens the login in Dia; `--no-open` only prints the link to
53
+ paste. From the studio: Configurações → Plataformas → **Conectar no Dia**
54
+ (Connect in Dia) or **Gerar link para copiar** (Generate a link to copy). The
55
+ link only works in a browser on this machine, because Google sends the login
56
+ back to `127.0.0.1`. It waits up to 10 min.
57
+
58
+ **Private until the audit.** New API projects can only upload videos as
59
+ private. Even if you ask for "Public", YouTube locks it as private. Until the
60
+ project is audited, publish as private and switch to public in YouTube Studio
61
+ (the link is in `publication.json`, at `youtube.studio`). To unlock it, request
62
+ the audit through the "YouTube API Services – Audit and Quota Extension" form
63
+ (Google answers in days or weeks). Once approved, set
64
+ `publish.youtube.audited: true` in the config.
65
+
66
+ **Quota.** 10,000 units per day, and each upload costs about 1,600: roughly 6
67
+ videos per day.
68
+
69
+ A 9:16 video up to 3 min becomes a Short on its own. Category, language and
70
+ "made for kids" live in `publish.youtube` in the config. If the video has
71
+ realistic synthetic content that needs a disclosure, use
72
+ `synthetic_content: true`.
73
+
74
+ ## Instagram (Reels)
75
+
76
+ 1. **Professional account.** In the Instagram app: Settings → Account type →
77
+ switch to **Creator** or **Business**. A personal account can't publish
78
+ through the API.
79
+ 2. **Meta app.** At [developers.facebook.com/apps](https://developers.facebook.com/apps),
80
+ create an app (use case: manage messaging and content on Instagram) and add
81
+ the **Instagram** product → "API setup with Instagram login".
82
+ 3. **You as a tester.** Under App roles → Roles, add your Instagram account as
83
+ an **Instagram tester** and accept the invite in Instagram (Settings → Apps
84
+ and websites → Tester invites). With the app in development mode and only
85
+ your account, there is no need to go through App Review.
86
+ 4. **Token.** Under "Generate access tokens", add the account and generate the
87
+ token with the `instagram_business_basic` and
88
+ `instagram_business_content_publish` permissions (for omnichat on comments,
89
+ also `instagram_business_manage_comments` and
90
+ `instagram_business_manage_messages`: `reference/omnichat.md`). Then run
91
+ `node tools/publish.mjs auth instagram <token>`.
92
+
93
+ The token lasts 60 days. `publish.mjs` renews it by itself when fewer than 20
94
+ days are left, on every publish or `status`. If more than 60 days pass without
95
+ publishing, generate another one (step 4).
96
+
97
+ **How the video gets there.** With Instagram login, Meta doesn't accept the
98
+ file: it downloads the video from a public URL (direct upload is only for apps
99
+ with Facebook login). `publish.mjs` opens that URL on the spot: a server on
100
+ `127.0.0.1` that serves only that MP4, at a random path, behind a `cloudflared`
101
+ quick tunnel (`https://<random>.trycloudflare.com/<token>.mp4`). The tunnel
102
+ takes about 15 s to respond, stays up until Instagram finishes processing and
103
+ closes right after. It needs `cloudflared` installed (`brew install
104
+ cloudflared`).
105
+
106
+ The video goes as Reels, also to the feed (`share_to_feed`). The cover is the
107
+ selected thumbnail (below, **Cover**); without one, the frame at `cover_at_s`
108
+ seconds (`null` = Instagram's choice). The post caption is the one in the
109
+ "Legenda" (Caption) field (the same as TikTok's), or the title and description
110
+ if it is empty: up to 2,200 characters and 30 hashtags. Reels through the API
111
+ accept 3 s to 15 min.
112
+
113
+ ## Carousel (Instagram)
114
+
115
+ `node tools/publish.mjs carousel videos/<slug> --confirm` (the button of the
116
+ carousel's Publicar stage in the studio does the same). It uploads
117
+ `carousel/export/NN.jpg` (exported on the spot if the build changed after the last
118
+ export) as a carousel post. Images don't go up as files either: each JPEG goes
119
+ through the same `cloudflared` tunnel as the Reel, becomes a child container
120
+ (`is_carousel_item`), and the `CAROUSEL` container joins the children with the
121
+ caption. The caption is `carousel/publication.json`'s (the one edited in the
122
+ studio) or `carousel.json`'s `caption`, with the Instagram footer and the
123
+ hashtags from `publish.text`. The API accepts 2 to 10 slides
124
+ (`carousel.slides.publish`) and images from 4:5 to 1.91:1: the app's 3:4 does not
125
+ go through it yet. The result (id, link, when) goes back to
126
+ `carousel/publication.json`, which prevents publishing twice (`--again` uploads
127
+ it again). `--auto` and the schedule do not publish carousels. After it goes up,
128
+ the carousel's omnichat is checked like the Reel's.
129
+
130
+ ## TikTok
131
+
132
+ 1. **App.** At [developers.tiktok.com](https://developers.tiktok.com), create an
133
+ app. Add the **Login Kit** (platform **Desktop**) and **Content Posting API**
134
+ (turn on **Direct Post**) products. Under scopes, request
135
+ `user.info.basic`, `user.info.profile`, `video.publish` and `video.upload`.
136
+ 2. **Credentials and redirect.** Copy the Client key and Client secret into
137
+ `.env` (or into Configurações → Plataformas → TikTok):
138
+ ```
139
+ TIKTOK_CLIENT_KEY=…
140
+ TIKTOK_CLIENT_SECRET=…
141
+ ```
142
+ Under Login Kit → Redirect URI, register `http://127.0.0.1:*/callback/`: the
143
+ login comes back to a free port on this machine.
144
+ 3. **You as a tester.** Until the app is approved, add your TikTok account under
145
+ Sandbox → Target users (or use the app in sandbox mode).
146
+ 4. **Login.** `node tools/publish.mjs auth tiktok` (or the button in
147
+ Configurações). The tokens go to `.env` (`TIKTOK_ACCESS_TOKEN`,
148
+ `TIKTOK_REFRESH_TOKEN`…). Access lasts 24 h and renews itself on every use; the
149
+ login lasts a year.
150
+
151
+ **Only me until the audit.** An unaudited app can only post directly as "Only
152
+ me" (`SELF_ONLY`), even if you ask for something else, and only to a **private
153
+ account**. On a public account TikTok refuses
154
+ (`unaudited_client_can_only_post_to_private_accounts`) and `publish.mjs` sends
155
+ it as a draft to the app's inbox, where you finish the post. To unlock it,
156
+ request the Content Posting API audit and set `publish.tiktok.audited: true`
157
+ (Configurações → TikTok → App auditado (App audited)).
158
+
159
+ **Draft.** With `publish.tiktok.mode: "draft"` the video goes to the TikTok
160
+ app's inbox, and you finish the post there (music, cover, text). It doesn't
161
+ depend on the audit.
162
+
163
+ Comments, duet, stitch, the AI-generated content label (`ai_content`) and the
164
+ cover (`cover_at_s`) live in `publish.tiktok`. The video needs at least 3 s,
165
+ and the maximum duration is whatever the account allows (publish checks it
166
+ first).
167
+
168
+ ## Cover
169
+
170
+ The cover is the thumbnail selected in the studio's Publicar stage ("Usar este
171
+ na publicação" (Use this one for publishing), or
172
+ `node tools/thumbnail.mjs videos/<slug> choose v2`), which becomes
173
+ `thumbnail/thumbnail.png`. `publish.mjs` reads it **at upload time**: a
174
+ scheduled post takes whatever is selected when the scheduler runs, and the form
175
+ shows which one will go. `node tools/publish.mjs cover videos/<slug>` says the
176
+ same in the terminal, without publishing anything.
177
+
178
+ | platform | how it goes |
179
+ |---|---|
180
+ | YouTube | `thumbnails.set` right after the upload, as a JPG up to 2 MB. The channel needs advanced features (phone verification, youtube.com/verify); without them, YouTube refuses with 403. On Shorts the API accepts it, but YouTube doesn't guarantee the cover in the Shorts feed |
181
+ | Instagram | `cover_url`, through the same temporary link as the video, instead of `cover_at_s` |
182
+ | TikTok | doesn't go: the API only accepts a frame of the video (`cover_at_s`) |
183
+
184
+ With no thumbnail selected, each platform uses its usual frame. A failing
185
+ cover doesn't bring the video down: it uploads (Instagram retries without the
186
+ cover), publish warns, and the result stores
187
+ `cover: { version, applied: false, error }`.
188
+
189
+ ## Schedule
190
+
191
+ In the Publicar stage, choose **Agendar** (Schedule), the day and time (this
192
+ Mac's time), and confirm. It is the same request as the Publicar button
193
+ (platforms, privacy, text), stored in `publication.json` (`schedule`) to go up
194
+ later. While it waits, the stage shows "agendada" (scheduled) and the card with
195
+ the time, from where it can be cancelled. Scheduling again replaces the previous
196
+ schedule.
197
+
198
+ To change only the time, drag the post in the studio's **Agenda** (Schedule)
199
+ screen, or
200
+ `node tools/publish.mjs schedule videos/<slug> --reschedule --when "2026-10-15 09:30" --confirm`.
201
+ Platforms, privacy and text stay; the state goes back to `scheduled` and the
202
+ attempts restart (a schedule that failed or missed its time, once rescheduled,
203
+ is valid again).
204
+
205
+ What publishes on time is the **scheduler agent**: a macOS LaunchAgent
206
+ (`~/Library/LaunchAgents/com.omnivideo.schedule.plist`) that runs
207
+ `publish.mjs scheduler run` every minute, with the studio open or closed. Turn
208
+ it on once in Configurações → Publicação → Agenda (Settings → Publishing →
209
+ Schedule) (or `scheduler install`). It uses the `node` of whoever installed it:
210
+ if you switch node versions, turn it on again. The log is in
211
+ `.schedule/schedule.log`.
212
+
213
+ - **Late.** A video that couldn't go up at its time still goes up to
214
+ `publish.schedule.max_delay_h` (12 h) after it; past that, it is **missed** and doesn't go up.
215
+ - **Failure.** A platform that fails retries on its own, up to
216
+ `publish.schedule.attempts` times (3), every `interval_min` (10 min). Then it
217
+ becomes **failed**, with the reason, waiting for you to schedule again or
218
+ publish now. The ones already up don't go up again.
219
+ - **Publishing by hand** a scheduled platform removes it from the schedule.
220
+ - **Instagram:** the `cloudflared` tunnel opens at publishing time, so the
221
+ internet has to be up at that time, as with the button.
222
+
223
+ ```bash
224
+ node tools/publish.mjs schedule videos/<slug> --when "2026-10-14 18:00" --youtube --tiktok --confirm
225
+ node tools/publish.mjs schedule videos/<slug> --cancel
226
+ node tools/publish.mjs scheduler # the agent and everything scheduled
227
+ node tools/publish.mjs scheduler install # turns the agent on (uninstall turns it off)
228
+ ```
229
+
230
+ ### In the cloud (cloud.schedule)
231
+
232
+ With `cloud.schedule: true` in the config, the Worker in `cloud/omnichat` publishes at the time. Scheduling does here what needs this
233
+ machine (the text, ffprobe, the cover JPEG and the omnichat rule the Reel will have, from
234
+ `omnichat.mjs published --plan`), uploads the MP4 and the cover to the cloud's R2 (deleted when the job
235
+ ends, or by a 7-day rule) and stores the job there; `--reschedule` and `--cancel` go to the cloud.
236
+
237
+ - **One short step a minute.** YouTube uploads in one; Instagram creates the container, then looks at
238
+ it each minute until it is processed, then publishes (it downloads the video from the Worker's
239
+ `/media/<key>`); TikTok uploads, then looks each minute. That keeps each run within the Workers Free
240
+ plan (10 ms of CPU, 50 subrequests). A failed step retries every `interval_min`, up to `attempts`.
241
+ - **The minute cron reads KV first** (`schedule:next`), so the database only wakes when something is
242
+ due.
243
+ - **When the Reel is live,** the cloud turns on its omnichat rule and adds it to the metrics right away.
244
+ - **This Mac's agent** only reads the outcome after the time (`scheduler run`) and writes the platform
245
+ entries into `publication.json`, as a local run would; until it does, the studio shows "agendada".
246
+ - **Credentials:** `publish.mjs cloud push` sends YouTube's and TikTok's (sealed there). TikTok renews
247
+ its refresh token on every renewal, so while the cloud schedules, this machine takes TikTok's newest
248
+ tokens from the cloud before using them and sends back what it renews: one chain, never two.
249
+ - A schedule made before the switch stays local: `cloud push` sends the pending ones up.
250
+
251
+ ## In the terminal
252
+
253
+ ```bash
254
+ node tools/publish.mjs text videos/<slug> # title, description and post caption from the script
255
+ node tools/publish.mjs videos/<slug> --youtube --instagram --tiktok --confirm
256
+ node tools/publish.mjs videos/<slug> --youtube --privacy unlisted --confirm
257
+ node tools/publish.mjs videos/<slug> --tiktok --tiktok-privacy FOLLOWER_OF_CREATOR --confirm
258
+ ```
259
+
260
+ `--confirm` exists because publishing goes outward: Claude only runs this when
261
+ the user asks. Scheduling also takes `--confirm`: it is the same request, made
262
+ now to go up later.
263
+
264
+ ## publication.json
265
+
266
+ ```json
267
+ {
268
+ "title": "…", "description": "…", "caption": "", "tags": ["…"],
269
+ "text_generated": { "at": "…", "by": "claude" },
270
+ "youtube": { "id": "…", "url": "https://youtube.com/shorts/…", "studio": "…", "privacy": "private",
271
+ "published_at": "…", "mp4": "export/<slug>.mp4", "mp4_mtime": 0 },
272
+ "instagram": { "id": "…", "url": "https://www.instagram.com/reel/…", "published_at": "…", "mp4": "…", "mp4_mtime": 0 },
273
+ "tiktok": { "id": "…", "publish_id": "…", "url": "https://www.tiktok.com/@…/video/…", "privacy": "SELF_ONLY",
274
+ "published_at": "…", "mp4": "…", "mp4_mtime": 0 }
275
+ }
276
+ ```
277
+
278
+ `caption_instagram` is the old name of `caption`: it is still read. In draft
279
+ mode, `tiktok` gets `"draft": true` and has no `url`. The TikTok link only
280
+ exists after the post becomes public and passes moderation.
281
+
282
+ When an attempt fails, the reason goes in `<platform>.last_error`. When a video
283
+ goes up again, the previous id goes to `<platform>.previous`.
284
+
285
+ With the Reel live, `publish.mjs` calls `omnichat.mjs published`: an omnichat
286
+ rule that is already enabled starts replying on it and, with
287
+ `omnichat.instagram.enable_on_publish`, a missing one turns on by itself
288
+ (`reference/omnichat.md`, On publish). An omnichat failure is a warning: it
289
+ doesn't bring the publication down.
290
+
291
+ When scheduled, the file gets a `schedule`, which is removed once everything is
292
+ up; each platform published by the scheduler stores the scheduled time in
293
+ `scheduled_for`:
294
+
295
+ ```json
296
+ "schedule": {
297
+ "when": "2026-10-14T21:00:00.000Z", "platforms": ["youtube", "tiktok"],
298
+ "privacy": "private", "tiktok_privacy": "SELF_ONLY", "republish": false,
299
+ "state": "scheduled", "attempts": 0, "created_at": "…", "origin": "studio"
300
+ }
301
+ ```
302
+
303
+ `state`: `scheduled` (waiting for the time or the next attempt, in
304
+ `next_attempt`), `publishing`, `failed` or `missed`; the reason for the last two
305
+ is in `last_error`.
@@ -0,0 +1,109 @@
1
+ # The `scenes.json` contract
2
+
3
+ One file per video, at `videos/<slug>/scenes.json`. It is the only source of
4
+ scene, beat, line, duration and position. Each field has **one** owning stage;
5
+ the others only read it. A full example is in `templates/scenes.example.json`.
6
+
7
+ ## Root
8
+
9
+ | field | owner | what it is |
10
+ |---|---|---|
11
+ | `slug` | 0 · open | `YYYY-MM-DD-subject`, also the export name (`export/<slug>.mp4`) |
12
+ | `title` | 1 · script | working title |
13
+ | `format` | 2 · motion script | `{ aspect: "9:16" \| "16:9", w, h, fps }` |
14
+ | `references` | 2 · motion script | library folders (`references.dir` in the config) the style came from: `["apura-paraguai"]` |
15
+ | `captions_in_motion` | 2, optional | `true` when the captions are drawn by the motion itself (from `OMNIVIDEO.video`); `assemble.mjs` does not burn the captions layer. `captions.srt` is still generated |
16
+ | `captions` | 8 · assembly, or the studio's Legenda (Captions) stage; optional | where the burned captions appear: `{ platform, anchor, x, y, style, scenes: { <scene>: { anchor?, x?, y? } }, individual: { <line>.<n>: { anchor?, x?, y?, hidden? } }, texts: { <line>.<n>: { text, original } } }` (`hidden: true` turns that caption off: assembly does not burn it; `texts` is the text edited in the studio, already written to `captions.srt`, and `original` is what the line generated). Each level overrides the previous one; whatever is missing comes from `captions.default_position` in the config. Rules in `reference/captions.md` |
17
+ | `voice` | optional | voice for this video only: `provider` (`fish`, `cartesia` or `voicestudio`; the others in the config's `voice.order` stay as fallback; the studio screen writes here), `speed` (applies to all lines), `voice_profile` (the `id` of a voice in the config's `voice.profiles`: its Fish `voice_id`, its Cartesia one and its VoiceStudio profile, plus the `order` to try them in; without it `voice.default_profile` applies, and with no voice at all each provider's `voice_id` and `voice.order`; a voice that no longer exists fails Fish and Cartesia with the reason, without switching voices), and for VoiceStudio `profile`, `language`, `num_step` |
18
+ | `preview` | legacy | the preview a video from before 2026-10-17 had approved (stage P no longer exists): ignored |
19
+ | `bed` | 3, optional | track under the video (music or texture), from `<video>/sfx/`: `"name.mp3"` or `{ name, db, from, to, trim, fade, loop, duck }`. `from`/`to` in seconds of the video (default: all of it); `loop` repeats the trim (texture only). Level: `sound.bed.level_db` below the voice, ducking `sound.bed.ducking_db`. The bed is isolated: `cuts` and `speed` never cut it or change its tempo; it plays straight through on the final timeline, ducked by the voice where the voice ends up (`from`/`to` say which part of the video it covers) |
20
+ | `speed` | 6 · studio Editor, optional | export speed, `1` to `1.5` (always written by the editor, even at `1`). `assemble.mjs` writes the base export at 100% (the editor's picture) and a second one, `export/<slug>-speed-<pct>.mp4`, that `assembly.json` then points to: picture, voice and effects sped up (voice without changing pitch), the bed not |
21
+ | `cuts` | 6 · studio Editor (the Corte de área (Range cut) tool), optional | `[{ from, to }]`, in seconds of scenes.json time (the video with no cuts at all), frame-aligned and non-overlapping: ranges removed from the export. `assemble.mjs` cuts at the end, with picture, captions and sound already assembled, and joins the rest; whatever crosses a cut loses only the part inside it. Voice, timing, render and `sound/` do not change. Conversions and rules in `tools/cuts.mjs`; `assembly.json` stores the cuts the export has |
22
+ | `scenes` | 2 · motion script | ordered list; the order is the timeline order |
23
+ | `total_duration` | 5 · `omnivideo.py timing` | sum of the scene durations |
24
+
25
+ ## Scene
26
+
27
+ | field | owner | what it is |
28
+ |---|---|---|
29
+ | `id` | 2 | `c01`, `c02`… |
30
+ | `title`, `goal`, `visual`, `hero` | 2 | what the scene communicates and shows; `hero` is the single highlighted element |
31
+ | `min_duration` | 3 | the minimum the motion needs, a multiple of 0.6 s |
32
+ | `html`, `mp4` | 2 | relative paths: `motion/c01.html`, `motion/c01.mp4` |
33
+ | `transition` | 3, optional | how the scene enters from the previous one: `"cut"` (default) or `{ "continues": ["card", "bg"] }`, the `data-continues` elements that must not jump at the cut. `sound` in the object (with or without `continues`) puts an effect on the cut, at the instant `scene.start` (same fields as a beat's `sound`). Ignored on the first scene |
34
+ | `beats` | 3 (`element`, `t`, `sound`) · 4 (`enters_with`, through `narrate.mjs apply`) | see below |
35
+ | `lines` | 4 (`id`, `text`, through `narrate.mjs apply`) · 5 · 7 | see below |
36
+ | `clips` | 6 · studio Editor (Navalha (Razor), drag, delete), optional | pieces of the scene MP4: `[{ from, to, offset, speed? }]`, `from`/`to` in seconds inside the MP4 (frame-aligned), `offset` how far the piece moves from its own place (negative moves it earlier) and `speed` (0.5 to 2, absent = 1) how fast the piece plays: it lasts (to − from) / speed from the same start, and what follows stays put (the gap holds the last frame). The Razor splits a clip in two; anything not in any clip was deleted. Without `clips`, the whole MP4 in place (or shifted by the old `video_offset`, which is still read). Beat and transition effects move with the piece they fall in (a beat in a deleted piece is dropped). `assemble.mjs` builds the picture with `tools/soundtrack.mjs`: where two pieces overlap, the one that started last shows, and in a gap the picture holds the last frame. A background that moves on video time may jump where a piece was shifted |
37
+ | `lead_in`, `hold` | 3, optional | seconds before the first line and after the last one, for this scene only (default: the config's `timing.lead_in` and `timing.final_hold`). A sentence that continues into the next scene uses `hold: 0` here and a comma-sized `lead_in` there |
38
+ | `duration` | 5 · `timing` | final duration, frame-aligned: `max(end of last line + hold, min_duration)` |
39
+ | `start` | 5 · `timing` | second at which the scene starts on the timeline |
40
+
41
+ ## Beat
42
+
43
+ | field | owner | what it is |
44
+ |---|---|---|
45
+ | `element` | 3 | name of what enters; becomes the CSS variable `--b-<element>` |
46
+ | `t` | 3 | provisional time in seconds, used until a voice exists |
47
+ | `enters_with` | 4 | reference to the line: `c01f2`, `c01f2:end`, `c01f2:palavra`, `c01f2:palavra#2`, with optional `+0.3`/`-0.3`. The word is the spoken (PT) word; `:fim` is still accepted as a legacy alias of `:end` |
48
+ | `sound` | 3, optional | effect on the beat: a file name in the global kit (`kit/sfx/kit.json`) or in `<video>/sfx/`, captured from Epidemic and registered in `sfx/sources.json` (`"clique-seco.mp3"`), an object with adjustments, or a list of them (layers at the same instant). Fields below |
49
+
50
+ `tools/timing.mjs` → `beatTime(scene, beat)` resolves it: `enters_with` if
51
+ present, otherwise `t`.
52
+
53
+ ### Fields of a `sound`
54
+
55
+ | field | default | what it is |
56
+ |---|---|---|
57
+ | `name` | required | file in the video's `sfx/` or in the global kit (`kit/sfx/`); the video's one wins. From the kit, the role's `db` is added (`sound.roles`) |
58
+ | `anchor` | `"peak"` | which point of the effect lands on the instant: `"peak"` (the loudest sample) or `"start"` |
59
+ | `offset` | 0 | seconds after the instant (negative: before) |
60
+ | `db` | 0 | adjustment over the default level: `sound.level_db` below the voice's integrated loudness |
61
+ | `trim` | whole file | `[from, to]` in seconds inside the file; `to: null` goes to the audible tail |
62
+ | `fade` | `[0, 0.05]` | `[in, out]` in seconds (4 ms fade-in when the trim does not start at 0) |
63
+ | `dur` | — | stretches or shrinks the trim to last this long, without changing pitch (continuous motion) |
64
+ | `speed` | 1 | speed factor; `dur` takes precedence. Limited to 0.25× to 4× |
65
+ | `pitch` | 0 | semitones, without changing duration |
66
+ | `duck` | `sound.ducking.db` | ducking under the voice for this effect only, in dB; `false` turns it off |
67
+
68
+ Each effect becomes `sound/<id>.wav` (`tools/sound.mjs`): id `<scene>-<element>`,
69
+ `<scene>-transition`, and `-2`, `-3`… for layers. The WAV comes out already
70
+ trimmed, processed, at volume and with ducking, starting at
71
+ `instant + offset − anchor`. The volume is measured after processing, by
72
+ perceived loudness (K-weighting over the `sound.window_s` window), not by peak.
73
+ `sound/plan.json` stores everything, including the voice segments that drive
74
+ the ducking.
75
+
76
+ ## Line
77
+
78
+ | field | owner | what it is |
79
+ |---|---|---|
80
+ | `id` | 4 | `<scene>f<n>`: `c01f1`, `c01f2` |
81
+ | `text` | 4 | what the voice says and the captions show, with final spelling and punctuation |
82
+ | `instruct` | 4, optional | style instruction for the voice (`"animado"`, `"sussurrando"`) |
83
+ | `wav`, `dur`, `hash` | 5 · `voice` | generated audio, duration in seconds, hash of text + voice + config of the provider that generated it |
84
+ | `provider`, `provider_requested` | 5 · `voice` | who generated the line and which provider the video had at that time; different = it came from fallback. A line with no `provider` predates providers (VoiceStudio) |
85
+ | `voice_profile` | 5 · `voice`, optional | the `id` of the voice (profile in `voice.profiles`) that spoke the line, for the studio player. Older lines don't have it; they show no voice name |
86
+ | `provider_pinned` | 5 · `voice`, optional | `true` when the line was generated with a provider chosen just for it (`voice --regenerate <line> --provider <id>`, the select next to "Gerar outra fala" (Generate another take)) or when the user picked a version from another provider in the studio (`voice --use`): it is a choice, not a fallback. The general `voice` run and `--regenerate-fallback` don't redo it, and it is left out of the mixed-voices warning. It disappears when the line is generated again without a choice |
87
+ | `start`, `end` | 5 · `timing` | position **inside the scene**, in seconds |
88
+ | `clips` | 6 · studio Editor, optional | pieces of the line's WAV, like the scene's `clips` (`from`/`to` in the audio, in ms; `speed` plays the piece faster with its pitch kept, through atempo). Without `clips`, the whole line in place. Captions and ducking move with the voice piece; a range outside the clips is silent and its caption is dropped |
89
+ | `words` | 7 · `captions` | `[{ w, s, e }]`, time of each word **inside the line**, measured on the audio (no transcription) |
90
+
91
+ Absolute time of a word on the timeline:
92
+ `scene.start + line.start + word.s`.
93
+
94
+ ## Invalidation
95
+
96
+ | changed | becomes invalid | who recomputes |
97
+ |---|---|---|
98
+ | `line.text` or the voice profile | `wav`, `dur` and everything that depends on timing | `voice` detects it by the hash and clears the line's `start`, `end`, `words` |
99
+ | any `dur` | `start`/`duration` of every scene | `timing` |
100
+ | a scene's `duration` | that scene's MP4 and the following MP4s, if some background moves on video time (`--scene-start`) | `build-motion.mjs --render` |
101
+ | `transition`, `data-continues` or `motion/src/_common.html` | the scenes on both sides of the cut | `build-motion.mjs --transitions --render` |
102
+ | a beat's or transition's `sound`, `bed`, the voice, or any timing | `sound/` (level and ducking depend on the voice) | `assemble.mjs` (redoes `sound/` by itself) |
103
+ | `captions` (position) or `motion/src/_captions.css` | the export | `assemble.mjs` |
104
+ | `cuts` or `speed` | the export (the background music is not cut or sped up) | `assemble.mjs` |
105
+ | `clips` (scene or line) | `sound/` (beats and ducking move) and the export | `assemble.mjs` |
106
+ | anything above | `captions.srt`, export | `captions`, `assemble.mjs` |
107
+
108
+ `omnivideo.py status` checks most of this, including whether each MP4's
109
+ duration matches `scene.duration`.